2013-02-13 6 views
7

C++ 11에서 멀티 스레드 코드를 실행하는 데 문제가 있습니다 (segfault). 여기C++ 11 std :: vector 동시 환경에서

#include <vector> 
#include <thread> 

std::vector<int> values; 
int i; 

void values_push_back() 
{ 
    values.push_back(i); 
} 

int main() 
{ 
    while(true) 
    { 
     std::vector<std::thread> threads; 

     for(i=0; i<10; ++i) 
     { 
      std::thread t(values_push_back); 
      threads.push_back(std::move(t)); 
     } 
     for(i=0; i<10; ++i) 
      threads[i].join(); 
    } 

    return 0; 
} 

그리고 GDB에 대한 역 추적 : http://pastebin.com/5b5TN70c

점에서 어떤 문제가 여기 코드인가?

+0

이 hmjds 답변을 내 댓글을보고 BL하지 마십시오 indly 그의 코드를 복사하십시오. – inf

답변

11

이것은 이동과 관련이 없습니다.

여러 스레드가 같은 vector하지만 vector::push_back()vector::push_back()을 실행하는 것은 스레드가 아닙니다. vector의 수정 사항을 동기화해야합니다.

std::mutexpush_back()에 대한 호출을 동기화하는데 사용될 수있다 :

std::vector<int> values; 
std::mutex values_mutex; 

void values_push_back() 
{ 
    values_mutex.lock(); 
    values.push_back(i); 
    values_mutex.unlock(); 
} 

또한, 가변 i (이의 가능한 결과 인 경쟁 상태가 발생할 것이다 동기화없이 스레드간에 공유되고 이 vector에 추가됨). 방지하기 위해 스레드에 인수로 int 값을 전달 이것을 고려 :

std::vector<int> values; 
std::mutex values_mutex; 

void values_push_back(int i) 
{ 
    values_mutex.lock(); 
    values.push_back(i); 
    values_mutex.unlock(); 
} 

for (int i = 0; i < 10; ++i) 
{ 
    threads.push_back(std::thread(values_push_back, i)); 
} 

for (auto& t: threads) t.join(); 
bamboonpush_back()가 발생하는 경우 잠금을 해제하기 위해 std::lock_guard을 선호하는 댓글을 달았으로

(이 경우에만 bad_alloc()을 할 수있는 있지만, vector 변경 생성자를 던지는 한 더 복잡한 개체를 보유하는 경우)를 더 중요하게 :

void values_push_back(int i) 
{ 
    std::lock_guard<std::mutex> lk(values_mutex); 
    values.push_back(i); 
} 
+0

간단한 코드로는 재현 할 수없는보다 복잡한 문제가있었습니다. 미안합니다. – deepskyblue86

+9

코드가 예외 안전하지 않습니다. push_back이 발생하면 교착 상태에 빠지며 대신'std :: lock_guard'를 사용하십시오. – inf

+1

@bamboon, 좋은 지적과 업데이트. – hmjd

관련 문제