2016-11-01 4 views
-1

다음 튜토리얼을 통해 읽었습니다 : C++ Multithreading Tutorial. 10 개의 고유 스레드를 생성하고 스레드 번호가있는 문자열을 인쇄하는 자습서의 코드를 컴파일했습니다. 여기뮤텍스 & 스레드 : 설명

코드가 링크를 열고 싶어하지 않는 사람들을위한 모습입니다 :

#include <iostream> 
#include <thread> 

static const int num_threads = 10; 

//This function will be called from a thread 

void call_from_thread(int tid) { 
    std::cout << "Launched by thread " << tid << std::endl; 
} 

int main() { 
    std::thread t[num_threads]; 

    //Launch a group of threads 
    for (int i = 0; i < num_threads; ++i) { 
     t[i] = std::thread(call_from_thread, i); 
    } 

    std::cout << "Launched from the main\n"; 

    //Join the threads with the main thread 
    for (int i = 0; i < num_threads; ++i) { 
     t[i].join(); 
    } 

    return 0; 
} 

내가 코드를 실행하면 컴파일 및 출력이 가지 무작위입니다. 각 스레드를 시작하지만 순서대로 시작하지는 않습니다.

std :: mutex에서 C++ 참조를 읽었으며 필자가 필요로하는 것처럼 들립니다.

그래서 누군가가 나에게 같은 표준 코드를 구현하는 방법에 대한 빠른 정리를 줄 수 있는지 궁금 해서요. 스레드가 동일한 공유 리소스를 사용하지 않도록 보장하고 순서대로 실행되도록합니다. .

+0

당신은 그들이 순서대로 시작하지 않았다고 생각합니까? 이 코드는 매우 명확하게 순서대로 실행합니다. –

+0

[Mutex example/tutorial?]의 가능한 복제본 (http : // stackoverflow.com/questions/4989451/mutex-example-tutorial) – TemporalWolf

+0

문제의'std :: mutex'는 어디에 있나요? 또한'std :: mutex'는 엄격한 실행 순서를 보장하지 않습니다. –

답변

1

스레드는 올바른 순서로 생성되지만 실행 스케줄링 순서는 동일하지 않을 수 있습니다.

뮤텍스가 솔루션입니까?

뮤텍스를 추가 할 수 있습니다.

std::mutex mtx; 

void call_from_thread(int tid) { 
    std::lock_guard<std::mutex> lock(mtx); // holds the lock until scope is left 
    std::cout << "Launched by thread " << tid << std::endl; 
} 

참고 그쪽으로 내가 직접 뮤텍스를 잠금하지 않았고 나는 lock_guard을 선호 : 이것은 두 개의 스레드가 동시에 임계 영역에없는 것을 보장합니다이 예외는 RAII를 사용하여 뮤텍스를 잠금 안전한.

Online demo 1

이 용액

에게 뮤텍스없이 멀티 스레딩을 수행하는 또 다른 방법은 원자이고, 원자 변수를 사용하는 것이다. 데이터 레이스없이 한 번에 하나의 스레드 만 액세스 할 수 있습니다.

std::atomic<int> cnt{0}; 

void call_from_thread(int tid) { 
    while (cnt!=tid) 
     std::this_thread::yield(); 
    std::cout << "Launched by thread " << tid << std::endl; 
    cnt++; 
} 

물론 위의 코드는 쓸모가 없습니다. 단지 스레드가 순서대로 실행되도록합니다. 모든 스레드는 글로벌 원자 카운터가 해당 숫자와 일치하는지 확인합니다. 그렇다면 글로벌 카운터를 실행하고 증가시킵니다. 그렇지 않은 경우 다른 스레드가 실행할 수있는 기회를 제공합니다.

Online demo 2

은 물론 여기에이 구조는 시간 낭비입니다. 일반적으로 조건 변수를 사용하면 이와 같은 작업을 수행 할 수 있습니다. 그것은 단지 삽화를위한 것입니다.

결론

멀티 스레딩은 매우 복잡하다. 파헤쳐보고 싶다면 앤서니 윌리엄 (Anthony William)의 책 "C++ Concurrency in action"을 적극 추천합니다. 이는 C++ 멀티 스레드 라이브러리뿐만 아니라 일반적으로 멀티 스레드 알고리즘의 문제점에 대한 단계별 소개로 훌륭한 단계입니다.