2013-10-27 5 views
0

이 코드가 있습니다. 여기에 전역 변수 c의 사용을 동기화해야합니까? 스트림이 동시에 작업을 시작하고 하나의 스레드가 다른 스레드의 결과를 덮어 쓰고 결국 2 또는 7 중 하나를 얻는 것이 가능합니까?전역 변수의 사용을 동기화해야합니다

#include <iostream> 
#include <stdio.h> 
#include <pthread.h> 
#include <stdlib.h> 

int c = 0; 

void* write(void*) 
{ 
    c += 2; 
} 

void* read(void*) 
{ 
    c += 7; 
} 

int main() 
{ 
    pthread_t t1; 
    pthread_t t2; 

    std::cout << "first C = " << c << std::endl; 
    int r1 = pthread_create(&t1, 0, &write, 0); 
    int r2 = pthread_create(&t2, 0, &read, 0); 
    pthread_join(t1, 0); 
    pthread_join(t2, 0); 
    std::cout << " C = " << c << std::endl; 

    return 0; 
} 
+2

뮤텍스 및 잠금에 익숙합니까? 편집 : 이것은 고전적인 독자 - 작가 문제입니다 : http://en.wikipedia.org/wiki/Readers%E2%80%93writers_problem – AndyG

+0

예, 나는 mutexes에 대해 잘 알고 있으며, URL에 감사드립니다. –

답변

1

예, 글로벌 변수에 대한 액세스를 보호해야합니다. mutex을 사용해야하거나 atomic 유형 (atomit 조작을 수정하는 경우)을 사용해야합니다.

이렇게하지 않으면 보통 +=에 읽기 작업이 필요하고 값을 추가 한 다음 결과를 다시 메모리에 씁니다. 두 스레드가 동시에이 작업을 수행하면 겹칠 수 있습니다. 예를 들어 두 코드 모두 예제 코드에서 0을 읽은 다음 두 결과 모두를 쓰면 마지막 쓰기 작업이 이기고 다른 추가 작업은 손실됩니다. 이미 의심스러운 경우 9 대신 2 또는 7으로 끝납니다.

1

개체에 동시에 액세스하는 스레드가 여러 개 있고 이러한 스레드 중 하나 이상이 개체를 변경하는 경우 개체에 대한 액세스가 동기화되어 있지 않으면 데이터 경쟁이 있습니다. 데이터 경주가있는 경우 프로그램의 동작은 정의되지 않습니다.

즉, 적절한 동기화를 사용하여 c에 액세스해야합니다.

0

별도의 데이터 캐시 메모리가있는 SMP 컴퓨터에서 고려해야 할 또 다른 미묘한 점이 있습니다 (스레드 간 메모리 동기화입니다). 스레드가 다른 코어/CPU에서 실행중인 경우 c을 업데이트하는 두 스레드가 정확히 같은 시간에 실행되지 않더라도 즉시 다른 스레드의 메모리 업데이트가 표시되지 않을 수 있습니다. 예를 들어 pthread_mutex_t을 사용하여 동기화하면이 문제가 해결됩니다.

pthread_join()은 다른 스레드와 메모리를 동기화하므로 스레드를 결합한 후 추가 조치가 필요하지 않으므로 c이 업데이트 된 값과 함께 표시됩니다.

다음은 다른 스레드와 메모리 동기화를 제공하는 POSIX 스레드 함수 목록입니다 (http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_11).