2013-04-06 5 views
7

이전에 cfm 페이지에서 cf 스코프에 관한 질문을했지만 (CFC 범위와 잠재적 인 문제점을 이해하고 기쁘게 생각합니다), 여전히 변수 범위에서 명확하지 않습니다.coldfusion CFM 변수 범위

이전 질문에 대한 답변에서 cfm 페이지를 사용하는 스레드 안전성 문제는 없으며 두 명의 다른 사용자가 동일한 페이지에 액세스하여 경쟁 조건이나 스레드 안전성 문제가있는 시나리오를 얻지 못할 것이라고 제안되었습니다 (심지어 내 변수를 기본 cfm 변수 범위에두고 각 사용자의 변수 범위가 격리되고 독립성이 있다고 가정합니다 (여기 마지막 질문은 Coldfusion Scopes Clarification입니다)

그러나이 블로그 게시물 http://blog.alexkyprianou.com/2010/09/20/variables-scope-in-coldfusion/에 관해서 읽었습니다. cfm 페이지에서 함수를 사용하고 변수 범위를 사용하는 것은 변수 범위가 여러 사용자가 공유하는 시나리오를 제안하는 것으로 보입니다. (나는 CFC의 맥락에서이 문제를 이해합니다. n은 자바 클래스와 변수 범위는 인스턴스 변수이기 때문에 CFC가 공유/응용 프로그램 범위/싱글 톤일 경우 스레드 안전성 문제가 있음) 그러나 이것은 이전 답변에 대한 카운터처럼 보입니다 - 변수가 cfm 페이지는 다른 사용자가 액세스 할 수 있습니다, 그렇다면 변수는 cfm 페이지 코드에서 직접 변수 범위에 배치됩니다.

필자는 몇 가지 명확한 문서 및 가이드가 필요했지만 실제로는 다른 범위와 사용 가능한 위치에 대한 명확한 설명을 찾을 수 없었습니다.

감사합니다.

+0

변수 범위가 공유 범위가 아니기 때문에 두 사용자가 경쟁 조건을 만들 수있는 문제는 없어야하지만 단일 사용자에게는 경쟁 조건이 발생할 수 있습니다. – BKK

+0

비동기 활동을 제쳐두고 경쟁 조건이있을 수 있습니까? 분명히 사용자가 페이지를 조회하면 단일 스레드 방식으로 순차적으로 실행됩니까? (비록 당신이 함수에서 지역 범위 변수를 사용하지 않는다면, 변수 이름을 재사용하고 혼란스러워 할 수 있으며, 이미 초기화 된 것을 인식하지 못한다고 생각합니다.) 또한 블로그 게시물이 잘못되었다고 말하고 있습니까? – rhinds

+0

블로그 게시물에서 그는 "request1"과 "request2"를 언급하고 있는데, 이들은 명시 적으로 2 명의 다른 사용자라고 말하고 있습니까? 나는 그런 인상을받지 못했다. 나는 일종의 멀티 코어 동시성 문제를 추측했다. – BKK

답변

12

댄은 정확하며 질문에 언급 된 블로그 기사는 단순히 잘못되었습니다. Dan의 코드가이를 보여줍니다. written-up and tested this thoroughly on my blog (너무 커서 여기에 올 수있었습니다).

CFM의 변수 범위는 각 요청의 변수 범위가 다른 메모리이기 때문에 이러한 종류의 경쟁 조건에서 안전합니다. 따라서 하나의 variables.foo은 다른 variables.foo과 같지 않으므로 교차하지 않습니다.

variable 범위의 객체에도 동일하게 적용됩니다. 내부 변수 scope은 별개의 엔터티이므로 원하는 수의 요청이 요청의 변수 범위에서 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]; }

하지만 다른 기능은 먼저이 실행 않지만 : 대

(I = 1, I < 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 스코프에 대한 혼란의 일부는 coldfusion 5의 공유 스코프와 관련이 없으며 안정성이 떨어집니다. 그들은 데이터 손상이나 충돌을 일으킬 수있는 심각한 스레드 안전 문제가있었습니다. 두 개의 스레드는 특정 조건에서 올바르게 잠그지 않으면 동일한 메모리에 동시에 쓸 수있었습니다. 현재 CFML 엔진은 손상/충돌 가능성없이 구조 키에 쓸 수 있습니다. 스레드 안전성을 고려하지 않고 실제로 어떤 데이터가 값으로 끝날지 확신 할 수 없지만 CFX, Java 및 기타와 같은 cfml 이외의 객체 유형을 처리하지 않는 한 일반적으로 손상되지 않습니다 . 스레드 안전 실수로 인해 무한 루프가 발생하여 시간이 초과 될 때까지 요청을 지연시킬 수 있지만 메모리가 부족하지 않으면 충돌이 발생하지 않아야합니다.

+0

@rhinds - 함수 변수를 지역화하지 못하면 [이 예제]와 같이 단일 스레드 내에서도 문제가 발생할 수 있음을 기억하십시오 (http://daveshuck.com/2006/11/28/thread-safety-example-var-scope- your-loop-index-in-coldfusion-cfcs /)가 보여줍니다. cfc를 사용하는 동안 함수가 .cfm 페이지에 있으면 동일한 결과를 얻습니다. 경쟁 조건 자체는 아니지만 항상 함수 변수를 지역화하는 것의 중요성을 보여줍니다. – Leigh

+1

Railo cfml 엔진 (getrailo.org)은 admin-> scope 페이지에서 "always"로 설정할 수있는 "local scope mode"옵션을 포함하고 있으므로 변수 범위가 아닌 모든 범위가 지정되지 않은 변수가 로컬이됩니다. Railo 4.1은 개별 기능에서도이 옵션을 지원합니다. 이 IMO 우수한 동작으로 마이그레이션하려는 경우 스레드 안전 코드로의 변환이 빨라집니다. 변수 범위 사용은 기본적으로 함수 또는 CFC의 잘못된 코드입니다. –

관련 문제