문제

가장 일반적인 플랫폼에서 (가장 중요한 것은 X86; 일부 플랫폼은 멀티 스레딩에 유용한 보장을 거의 제공하지 않지만 희귀 한 카운터 샘플에 관심이 없음)는 다음과 같은 코드가 안전합니까?

스레드 1 :

someVariable = doStuff();
atomicSet(stuffDoneFlag, 1);

스레드 2 :

while(!atomicRead(stuffDoneFlag)) {}  // Wait for stuffDoneFlag to be set.
doMoreStuff(someVariable);

원자 OPS의 표준, 합리적인 구현을 가정합니다.

  1. 스레드 1의 할당입니다 someVariable 이전에 완료하도록 보장됩니다 atomicSet() 호출 되나요?
  2. 스레드 2는 과제를 볼 수 있도록 보장됩니다 someVariable 전화하기 전에 doMoreStuff() 그것이 읽는 경우 stuffDoneFlag 원자 적?

편집 :

  1. 내가 사용하고있는 원자력 작전의 구현에는 x86이 포함되어 있습니다. LOCK 도움이되는 경우 각 작업에 대한 지침.
  2. 추정하다 stuffDoneFlag 어떻게 든 제대로 지워집니다. 얼마나 중요하지 않습니다.
  3. 이것은 매우 단순화 된 예입니다. 나는 당신이 문제의 전체 맥락을 이해할 필요가 없도록 이런 식으로 만들었습니다. 나는 그것이 효율적이지 않다는 것을 알고 있습니다.
도움이 되었습니까?

해결책

실제 X86 코드에 스레드 1의 AtomicSet의 매장에 상점이 있고 스레드 2의 AtomicRead에서로드 후 약간의 부하가 있으면 괜찮을 것입니다. 인텔의 소프트웨어 개발자의 매뉴얼 볼륨 3A 8.2 절에서 x86에 대한 메모리 모델을 지정하고 스레드 내 스토어 스토어 및로드로드 제약 조건으로 충분해야합니다.

그러나 컴파일러가 원자 운영에서 사용하는 상위 수준의 언어에서 생성 된 지침을 재정렬하는 것을 방해하지 않을 수 있습니다.

다른 팁

1) 예

2) 예

두 작업.

이 코드는 스레드가 안전하게 보이지만 귀하의 효율성에 의문 스핀 락 (while 루프) 아주 짧은 시간 동안 만 회전하지 않는 한. 주어진 시스템에서 스레드 2가 모든 처리 시간을 완전히 호그하지는 않는다는 보장은 없습니다.

실제 동기화 프리미티브를 사용하는 것이 좋습니다 ( 부스트 :: 조건 _variable 스핀 잠금 장치에 의존하는 대신 여기에서 원하는 것입니다.

원자 지침은 스레드 2가 스레드 1을 기다리며 스레드 2가 진행되기 전에 변수를 설정하기 위해 스레드 1을 기다립니다. 그러나 두 가지 주요 문제가 있습니다.

1) someVariable 선언해야합니다 '휘발성 물질'컴파일러가 최적화되지 않도록하기 위해 등록부에 저장하거나 쓰기를 연기하는 할당됩니다.

2) 두 번째 스레드는 신호를 기다리는 동안 차단됩니다 ( 스핀 로킹). 귀하의 플랫폼은 아마도 훨씬 더 나은 잠금 및 신호 전기 및 메커니즘을 제공하지만 비교적 간단한 개선은 간단하게 개선 될 것입니다. sleep() 스레드 2에서 while() 신체.

Dsimcha는 다음과 같이 썼습니다.이것은 사실이 아닙니다!

시나리오를 보자 :

  1. STREAD2는 stuffDoneflag가 1 인 경우 약간의 평가를 시작합니다.
  2. Thread2가 완료되기 전에 작업 스케줄러가 작업을 방해하고 한동안 작업을 중단합니다.
  3. Thread1은 다시 한 번 약간의 가치에 액세스하고 메모리 컨텐츠를 변경합니다.
  4. 작업 스케줄러 스위치가 다시 켜져 있으며 작업을 계속하면 작업이 계속되지만 일부 변환 가능의 메모리 컨텐츠가 변경됩니다!
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top