带有 std::promise 的 C++11 分段错误

Posted

技术标签:

【中文标题】带有 std::promise 的 C++11 分段错误【英文标题】:C++11 Segmentation fault with std::promise 【发布时间】:2015-07-18 11:51:02 【问题描述】:

C++ std::promise 分段错误

此代码创建多个线程并向它们发送promise&。当他们调用 promise::set_value 尝试将数据返回给 main 时,它会出现段错误。

谁能解释为什么这段代码会产生分段错误?

void workerFunc(promise<long>& prom) 

    long number = doInterestingThings();
    //SEGFAULT!!!
    prom.set_value(number);
    return;

线程函数。它在prom.set_value 处出现段错误。如果我只创建 1 个线程,则不会这样做。

int main (int argc, char** argv) 
    vector<promise<long>> promises;
    vector<future<long>> futures;
    vector<thread> workers;

初始化。

    const int createThisMany = 6;
    for (int i = 0; i < createThisMany; i++) 
        promises.emplace_back();
        futures.push_back(promises.back().get_future());
        workers.emplace_back(workerFunc, std::ref(promises.back()));
    

创建所有线程和promisefuture 对象。不包括监控向量和删除死线程等的主循环。

promise 和 futures 是否必须同步?

我在 Lubuntu 14.04 上使用 gcc 4.9

【问题讨论】:

【参考方案1】:

你不能分享承诺。 移动它们:

 workers.emplace_back(workerFunc, std::move(promises.back());

还有:

void workerFunc(promise<long> prom);

这意味着您可能也不需要空承诺向量:

promise<long> pr;
futures.push_back(pr.get_future());
workers.emplace_back(workerFunc, std::move(pr));

【讨论】:

【参考方案2】:

promises.emplace_back(); 可能导致向量重新分配和所有包含的对象位置(引用、迭代器)无效。你有悬空引用。

在存储将发送给数据消费者的未来之后,将承诺移动到将履行承诺的代码中。

请注意,MSVC 在 2013 年搞砸了一些承诺。

【讨论】:

谢谢!奇怪的是,我只是假设 push_back() 或 emplace_back() 永远不会重新分配向量。现在我移动了 promise 而不是 ref,它不再崩溃了。

以上是关于带有 std::promise 的 C++11 分段错误的主要内容,如果未能解决你的问题,请参考以下文章

[C++11 多线程异步] --- std::promise/std::future

C++11promise和future介绍

C++11promise和future介绍

C++11promise和future介绍

[C++11 多线程异步] --- std::promise/std::future

[C++11 多线程异步] --- std::promise/std::future