2014-04-11 3 views
1

원자 포스트 증가가 실제로 어떻게 작동하는지 혼란스러워합니다. std :: atomic <> 후 증가분은 언제 발생합니까?

std::atomic<int> a = 1; // global 
void func(int i) { 
    std::cout << i; 
} 

// execute the following in two threads 
func(a++); 

예를

위해 나는 a 마침내 3이되고 있지만, 출력 "11"을 참조 할 수 있습니다 생각? 두 스레드 중 하나가 a이 2가된다는 것을 확실히 예상 할 수 있습니까?

+0

"a가 원자가 아닌 경우 func가 반환 된 후 후행 증가가 발생합니다 "당신은 그것에 대해 확신하고 있습니까? – WhozCraig

+0

@WhozCraig 내가 잘못 했어. 지적 해 주셔서 감사합니다. – GuLearn

답변

3

코드가 그대로 컴파일되지 않습니다. std::atomic<int>은 복사 생성을 허용하지 않습니다.

을 FUNC하는 a의 사본을 전달 a

  • 의 사본 증가 a
  • 합니다

    첫째, a 원자 아니었다면이 작품은 어떻게 볼 수 있습니다 원자의 경우 (func를 int으로 수정한다고 가정), copy/increm ent는 원자 적으로 발생합니다. 복사본은 여전히 ​​func로 전달됩니다.

    증가/복사가 원자 단위이기 때문에 ++을 호출하는 첫 번째 스레드는 1에서 2로 증가시키고 1을 func로 전달합니다. 두 번째 것은 2에서 3으로 증가하고, 2는 func에 전달합니다. func에 대한 호출 순서는 결정적이지 않지만 값 1로 한 번, 값 2로 한 번 호출해야합니다.

  • +0

    답변 해 주셔서 감사합니다. 'a'가 마침내 3이 되더라도 "11"은 여전히 ​​데이터 경쟁으로 간주됩니까? – GuLearn

    +0

    @ YZ.learner : 코드가 func로 변경되면 '11'이 표시되지 않습니다. 증분은 각각'fetch_add (1)'을 호출해야하는데, 기본적으로 순차적 일관성을 사용하며, 순차적 일관성을 사용하여 깨끗하게 증가시킵니다. 이제 '21'또는 '12'를 쉽게 볼 수 있습니다. –

    관련 문제