2013-04-06 3 views
7

Ранее я задал вопрос о cf scopes на страницах cfm (счастлив, что я понимаю области CFC и потенциальные проблемы), но до сих пор неясно в области переменных.coldfusion CFM Variables scope

В ответах на мой предыдущий вопрос было высказано предположение, что с использованием страниц cfm не возникает проблем с потоковой безопасностью, и вы не получите сценарий, когда два разных пользователя получают доступ к одной странице и имеют условия гонки или проблемы безопасности потоков (даже если я просто оставлю переменные в области переменных cfm по умолчанию и что область переменных для каждого пользователя будет изолирована и независима (вот мой последний вопрос Coldfusion Scopes Clarification)

Тем не менее, я прочитал это сообщение в блоге http://blog.alexkyprianou.com/2010/09/20/variables-scope-in-coldfusion/ относительно использование функций на странице cfm и использование области переменных и, по-видимому, предполагает сценарий, в котором область видимости переменных распределяется между несколькими пользователями (я понимаю эту проблему в контексте ХФУ - их больше аки n для классов java и области переменных, являющихся переменными экземпляра, так что проблемы с безопасностью потоков, если CFC является общим/областью приложения/singleton), но это похоже на предыдущие ответы - если переменная помещается в область переменных с помощью функции на cfm страница может быть доступна другим пользователям, то, конечно, переменные, помещенные в область переменных напрямую в код страницы cfm, одинаковы?

Я надеялся на некоторые четкие документы и руководства, но не смог найти окончательного объяснения различных областей и где они доступны.

Спасибо!

+0

Поскольку область видимости переменных не является общей областью, не должно быть проблем, когда два пользователя могут создать условие гонки, однако возможно, что состояние гонки может случиться с одним пользователем. – BKK

+0

Асинхронная деятельность в стороне, как может быть состояние гонки? Разумеется, когда пользователь нажимает на страницу, он выполняется в одном поточном, последовательном порядке? (Я признаю, что если вы не используете локальные переменные области в функциях, это может запутаться при повторном использовании имен переменных, а не в том, что вещи уже инициализированы). Кроме того, вы говорите, что сообщение в блоге неверно? – rhinds

+0

В блоге он ссылается на «request1» и «request2», он явно говорит, что это два разных пользователя? У меня не было такого впечатления, я догадывался о какой-то проблеме многоядерного параллелизма. – BKK

ответ

12

Дэн правильный, и статья в блоге, на которую ссылается в вопросе, просто неверна. Код Дэн демонстрирует это, и у меня есть written-up and tested this thoroughly on my blog (он был слишком большой, чтобы идти сюда).

Суть заключается в том, что область переменных в CFM безопасна из такого рода условий гонки, поскольку область переменных для каждого запроса является другой памятью. Таким образом, один variables.foo не совпадает с другим variables.foo, поэтому ни разу не пересекайтесь.

То же самое относится к объектам в области переменных: их область внутренних переменных - это отдельный объект, поэтому любое количество запросов может создавать экземпляр CFC в области переменных запроса, а области переменных экземпляров CFC - все дискретные объекты тоже ,

Единственный раз, когда область видимости переменных может участвовать в состоянии гонки, является областью переменных объекта, хранящегося в общей области. Поскольку все ссылки на этот объект с общими областями будут ссылаться на один и тот же объект в памяти, так что объем переменных одного и того же объекта в памяти.

3

Я думаю, что блог вводит в заблуждение. Однако, если вы хотите сами убедиться, напишите страницу со своей функцией. Сделайте так, чтобы это выглядело так.

<cffunction name="test" returntype="void"> 
<cfscript> 
foo = now(); 
sleep(3 * 60 * 1000); // should be 3 minutes 
writedump(foo); 
</cfscript> 
<cffunction> 

<cfdump var="#now()#"> 
<cfset test()> 

Запустите страницу. В течение 3 минут откройте другой браузер или вкладку и запустите ее снова. Вернитесь туда, где вы его запустили, и дождитесь результатов. Если между двумя выходами нет существенной разницы, ваш второй запрос страницы не повлияет на ваш первый.

Заметьте, что я не пробовал это сам, но моя ставка была бы на втором запросе, не затрагивая первый.

4

Функции вне CFC, доступ к области переменных не будут иметь проблем с потоковой безопасностью, когда 2 запроса запускают код, но если вы используете cfthread или другие параллельные функции, у вас все еще могут быть проблемы с изменяемой областью переменных, и это может привести к условиям гонки.Часто эта ошибка может возникать с переменной, которую вы используете много, например, в цикле for, переменной «i».

для (i = 1; i < 10; i ++) {t = arr [i]; }

Но тогда другая функция делает это в то время как первая работает:

для (я = 1; я < 20; я ++) {T = обр [I]; }

Переменная «i» должна стать локальной переменной, чтобы сделать ее потокобезопасной. Вы не хотите, чтобы первый цикл мог пройти выше 10 по ошибке, и это сложно отлаживать много раз. Я должен был исправить тонну переменных «i» и других, чтобы сделать мои функции потокобезопасными везде, когда я начал кэшировать объекты и более активно использовать cfthread.

Вы также можете избежать блокировки, не меняя существующие объекты. Вместо этого вы можете работать над копиями. Это делает данные «неизменными». CFML не имеет официальной поддержки для создания неизменяемых объектов более эффективно, но вы можете делать копии легко. http://en.wikipedia.org/wiki/Immutable_object

Простой пример резьбы безопасного изменения в переменной объем применения:

var temp=structnew(); 
// build complete object 
temp.myValue=true; 
// set complete object to application scope variable 
application.myObject=temp; 

Запись в любой общий объект часто является опасным, так как переменные могут быть неопределенным или частично построен. Я всегда создаю полный объект и устанавливаю его в общую переменную в конце, как в примере выше. Это облегчает безопасность потоков, если не слишком дорого воссоздать данные. Область переменных в CFC аналогична переменной частного члена на других языках. Если вы изменяете данные в общих объектах, вы могли бы использовать CFLOCK, если вы не можете делать копии вместо этого.

Некоторые из путаницы в области холодного воздуха связаны с общими областями в coldfusion 5 и ранее менее надежными. У них были серьезные проблемы с безопасностью резьбы, которые могут привести к повреждению данных или сбоям. Два потока в определенных условиях могли записывать в одну и ту же память одновременно, если вы не заблокировали их правильно. Современные двигатели CFML умеют писать в структурные ключи без возможности коррупции/сбоев. Вы просто не можете быть уверены, какие данные будут на самом деле заканчиваться как ценность без некоторого рассмотрения безопасности потоков сейчас, но она обычно не будет повреждена, если вы не имеете дело с типами объектов, отличными от cfml, такими как CFX, Java и другие , Ошибка безопасности потока может по-прежнему приводить к бесконечному циклу, который может повесить запрос до тех пор, пока он не истечет, но он не должен терпеть крах, если у него не осталось памяти.

+0

@ rhinds - Имейте в виду, что не удается локализовать функциональные переменные, может вызвать проблемы даже в пределах одного потока, как [этот пример] (http://daveshuck.com/2006/11/28/thread-safety-example-var-scope- ваш-loop-index-in-coldfusion-cfcs /). Хотя он использует cfc, вы получаете тот же результат, если функции размещены на странице .cfm. Не состояние гонки как таковое, но оно действительно иллюстрирует важность локализации переменных функции - всегда. – Leigh

+1

Я хочу упомянуть, что движок C++ (RailAilo.org) имеет параметр «Локальный режим области видимости» на странице администрирования -> scope, который может быть установлен как «всегда», что сделает все переменные нераспространения локальными, а не переменными. Railo 4.1 будет поддерживать эту опцию и для отдельных функций. Это ускоряет преобразование в потокобезопасный код, если вы планируете перенестись на это поведение ИМО. Использование области переменных по умолчанию - это плохой код в функции или CFC. –

Смежные вопросы