2013-02-13 240 views
7

我有一个问题(段错误)在C++ 11中运行多线程代码。这是代码:并发环境中的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 2013-02-14 22:06:56

回答

11

这与移动无关。

多个线程在同一vectorvector::push_back()执行vector::push_back()不是线程安全的。需要对vector的修改进行同步。

std::mutex可以用来调用同步push_back()

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

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

此外,可变i被线程之间共享,而不同步其将导致的竞争条件(这一个可能的结果是重复int s被添加到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(); 

正如评论说bamboon喜欢std::lock_guard,以确保如果push_back()抛出锁被释放(在这种情况下,只能是bad_alloc()但如果vector变化来保存已经扔构造更复杂的对象变得更加重要):

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

我有一个更复杂的问题,我无法用简单的代码重现。对于那个很抱歉。 – deepskyblue86 2013-02-13 18:22:58

+9

您的代码不是异常安全的。如果push_back抛出,则会死锁,请改用'std :: lock_guard'。 – inf 2013-02-14 22:04:50

+1

@bamboon,好点,并更新。 – hmjd 2013-02-15 08:43:37

相关问题