【问题标题】:C++11 std::vector in concurrent environment并发环境中的 C++11 std::vector
【发布时间】:2013-01-29 08:11:48
【问题描述】:

我在 C++11 中运行多线程代码时遇到问题(段错误)。这是代码:

#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

这有什么问题?

【问题讨论】:

  • 请看我对hmjds答案的评论,不要盲目复制他的代码。

标签: c++ multithreading concurrency c++11 segmentation-fault


【解决方案1】:

这与移动无关。

多个线程在同一个vector 上执行vector::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 在线程之间共享而没有同步,这将导致竞争条件(可能的结果是重复的ints 添加到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);
}

【讨论】:

  • 我遇到了一个更复杂的问题,我无法用简单的代码重现。对此感到抱歉。
  • 您的代码不是异常安全的。如果 push_back 抛出,你会死锁,请改用std::lock_guard
  • 还要考虑 #include 和 boost::lockfree::queue 值 {100};
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-05-07
  • 1970-01-01
  • 2016-07-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多