2010-04-08 2 views
5

스레드가 Delphi VCL 이벤트로 설정된 변수를 읽는 것이 안전합니까?스레드가 VCL 이벤트로 설정된 변수를 안전하게 읽을 수 있습니까?

사용자가 VCL TCheckbox를 클릭하면 주 스레드는 확인란의 Checked 상태를 부울로 설정합니다. 언제든지

CheckboxState := CheckBox1.Checked; 

는 스레드 읽는 변수

if CheckBoxState then ... 

스레드 부울 변경을 "그리워"만일 스레드가 루프 등의 변수를 확인하기 때문에 이것은 문제가되지 않는다 그것은 다른 일을합니다. 그러면 결국 국가 변경이 표시됩니다 ...

안전한가요? 아니면 특별한 코드가 필요합니까? 중요한 코드 호출이 충분하고 충분하면 (각각 스레드와 메인 스레드에서) 변수의 읽기 및 쓰기를 둘러 쌉니까?

내가 말했듯이 스레드가 "잘못된"값을 얻는지는 중요하지 않지만 주 스레드가있는 동안 한 스레드가 변수를 읽으려고하면 저수준 문제가 발생할 수 있다고 생각합니다. 그것을 쓰는 중간, 또는 그 반대입니다.

제 질문은 Cross thread reading of a variable who's value is not considered important과 비슷합니다.

(또한 내 앞의 질문에 관련된 : Using EnterCriticalSection in Thread to update VCL label) 당신이주는 예를 들어

+0

VCL 이벤트는 실제로 특별한 것이 아닙니다. 귀하의 질문은 * 모든 * 두 스레드의 * 모든 종류의 함수에서 변수에 액세스하는 데 똑같이 적용됩니다. –

답변

6

이 세 가지 이유, 안전 :

  • 하나 개의 스레드는 변수에 기록합니다.

  • 변수는 단지 1 바이트이므로 일치하지 않는 값을 읽을 방법이 없습니다. True 또는 False으로 읽습니다. Delphi boolean 값과 정렬 문제는 있어서는 안됩니다.

  • 델피 컴파일러는 변수가 실제로 쓰여졌는지 여부에 대한 광범위한 검사를하지 않으며, 그렇지 않은 경우 코드를 "최적화"하지 않습니다. 지역 변수가 아닌 변수는 항상 읽히므로 volatile 지정자가 필요하지 않습니다.

은 이것에 대해 정말 모르는 경우 부울 대신 integer 값을 사용하고, 변수에 쓸 InterlockedExchange() 기능을 사용할 수 있다고 말했다 가졌어요. 이것은 지나치게 잔뜩 들었지만 단일 기계 단어 크기 값의 경우 잠금이 필요하지 않을 수 있으므로 잘 알고있는 기술입니다.

또한 boolean을 이벤트와 같은 적절한 동기화 프리미티브로 바꿀 수 있으며 스레드 블록을 사용하여 스레드의 통화 중 루프를 제거하는 데 도움이됩니다.

1

, 그것은 안전합니다. 기술적으로 중요한 문제는 변수가 기계어 크기 이상인 경우이며, 따라서 높은 단어와 긴 단어가 동기화되지 않을 수 있습니다. 작은 값이라도 문제는 아닙니다.

예를 들어 포인터를 사용하는 것과 같은 잠재적 인 문제라고 생각되는 항목은 항목에 대한 읽기 및 쓰기를 제어하는 ​​TCriticalSection입니다. 이것은 모든 실제 상황에 충분히 빠르며 100 % 안전을 보장합니다.

3

귀하의 경우 (체크 된 속성) 읽기 작업은 원자 적이므로 안전합니다. TThread.Terminated 속성과 동일합니다. 제대로 정렬 된 바이트, 단어 및 더블 워드에 대한 간단한 읽기 및 쓰기 작업은 원 자성입니다. 당신은 자세한 내용은 intel documentation을 확인할 수 있습니다

제 8 장 - 다중 프로세서 관리

8.1.1 보장 원자 운영

기본 메모리 작업을 다음한다는 Intel486 프로세서 (이후 새로운 프로세서) 보장 항상 원자 적으로 수행됩니다

  • 읽기 또는 바이트
  • 읽기 쓰기 또는를 작성 워드는 16 비트 경계
  • 읽기 정렬 또는 32 비트 경계

(사람 및 최신 프로세서) 펜티엄 프로세서 정렬 더블을 작성하는 것은 다음 추가 메모리 동작이 항상 수행 될 것이라는 보장 아웃 원자 적 :

  • 읽거나
  • 16 비트는 32 비트 데이터 버스에 맞 캐시되지 않은 메모리 위치에 액세스하는 64 비트 경계로 정렬 된 쿼드 워드를 쓰기
관련 문제