2013-10-10 4 views
3

C++ 11 스레딩 라이브러리를 사용하여 멀티 스레딩 (일반적으로 멀티 스레드)을 시작했으며 작은 코드를 작성했습니다.C++ 11 스레드를 사용하여 스레드 간 강제 실행

#include <iostream> 
#include <thread> 

int x = 5; //variable to be effected by race 

    //This function will be called from a thread 
    void call_from_thread1() { 
    for (int i = 0; i < 5; i++) { 
      x++; 
      std::cout << "In Thread 1 :" << x << std::endl; 
     } 
    }  

    int main() { 
     //Launch a thread 
     std::thread t1(call_from_thread1); 

     for (int j = 0; j < 5; j++) { 
      x--; 
      std::cout << "In Thread 0 :" << x << std::endl; 
     } 

     //Join the thread with the main thread 
     t1.join(); 

    std::cout << x << std::endl; 
    return 0; 
    } 

두 스레드 간의 경쟁으로 인해이 프로그램을 실행할 때마다 (또는 매 시간마다) 다른 결과가 나올 것으로 예상됩니다. 그러나 출력은 항상 : 0입니다. 즉 두 개의 스레드가 순차적으로 실행되는 것처럼 실행됩니다. 왜 내가 같은 결과를 얻고 두 스레드 사이에서 경쟁을 시뮬레이션하거나 강제 할 수있는 방법이 있습니까?

+2

그래서 경쟁 조건은 항상 * 정의되지 않은 * 동작입니다. ;) –

+0

CPU에는 몇 개의 코어가 있습니까? – DeathByTensors

+0

코어 4 개, 코어 i3 – newprint

답변

8

샘플 크기가 다소 작으며 연속 stdout 플러시에서 약간 자체적으로 멈 춥니 다. 즉, 더 큰 망치가 필요합니다.

실제 경기 상황을보고 싶다면 다음을 고려하십시오. 나는 의도적으로 샘플의 스레드에 둘 다 보내는 원자 및 비 원자 카운터를 추가했습니다. 일부 테스트 실행 결과는 코드 다음에 게시되어 있습니다 :

#include <iostream> 
#include <atomic> 
#include <thread> 
#include <vector> 

void racer(std::atomic_int& cnt, int& val) 
{ 
    for (int i=0;i<1000000; ++i) 
    { 
     ++val; 
     ++cnt; 
    } 
} 

int main(int argc, char *argv[]) 
{ 
    unsigned int N = std::thread::hardware_concurrency(); 
    std::atomic_int cnt = ATOMIC_VAR_INIT(0); 
    int val = 0; 

    std::vector<std::thread> thrds; 
    std::generate_n(std::back_inserter(thrds), N, 
     [&cnt,&val](){ return std::thread(racer, std::ref(cnt), std::ref(val));}); 

    std::for_each(thrds.begin(), thrds.end(), 
     [](std::thread& thrd){ thrd.join();}); 

    std::cout << "cnt = " << cnt << std::endl; 
    std::cout << "val = " << val << std::endl; 
    return 0; 
} 

일부 샘플 실행을 위의 코드에서 : 원자 카운터가 정확하다는 것을

cnt = 4000000 
val = 1871016 

cnt = 4000000 
val = 1914659 

cnt = 4000000 
val = 2197354 

주 (I는 듀오 코어에서 실행 해요 i7 맥북 에어 랩탑, 하이퍼 스레딩, 4x 스레드, 따라서 4 백만). 비 원자 카운터에 대해서도 마찬가지입니다.

3

두 번째 스레드를 시작하는 데 상당한 시작 오버 헤드가 발생하므로 첫 번째 스레드가 for 루프를 완료 한 후 거의 항상 실행됩니다. 비교는 거의 시간이 걸리지 않습니다. 경쟁 조건을 보려면 훨씬 더 오래 걸리거나 상당한 시간이 걸리는 I/O 또는 다른 연산을 포함하는 계산을 실행해야하므로 두 계산의 실행이 실제로 겹치게됩니다.

+0

설명해 주셔서 감사합니다. – newprint