Too*_*one 0 c++ multithreading c++11
我正在学习C++ 11的功能,并按照以下几行编写了一些代码
#include <vector>
#include <thread>
using std::thread;
using std::vector;
double Computation(int arg)
{
// some long-running computation
return 42.0;
}
double ConcurrentComputations()
{
const int N = 8; // number of threads
vector<thread> thr;
vector<double> res(N);
const int arg = 123456; // something or other
// Kick off threads which dump their results into res
for(int i=0; i<N; ++i)
thr.push_back(thread ([&res, i, arg]()
{ res[i] = Computation(arg); } ));
// Wait for them to finish and get results
double sum = 0;
for(int i=0; i<N; ++i) {
thr[i].join();
sum += res[i];
}
return sum;
}
Run Code Online (Sandbox Code Playgroud)
在寒冷的白天再看一遍,我认为我真的不应该vector在lambda函数中引用a 并将数据转储到其中.我正在考虑将矢量作为常规数组并依赖于operator[]简单添加的i实现&res.front()(也许我应该已经捕获了&res.front(),现在我已经在Stroustrup 4ed中进一步阅读了,我可以看到我应该使用期货和承诺) .
然而,我的问题是,认为在实践中我可以逃脱我写的代码是否合理?
你的代码实际上很好!(当混合线程时,默认情况下代码通常会被破坏,但在这种情况下不会.)
声明vector<double> res(N);将为所有结果初始化具有足够空间的数组,因此向量将永远不会在循环中调整大小.
每个线程只写入向量的不同元素,并且线程构造函数和join()方法中存在隐式内存屏障,这些屏障按照您的预期保持排序.
现在,关于这是否实际上是由标准支持 - 嗯,可能不是(我发现关于std :: vector的线程安全的大多数引用只保证读取,而不是写入).捕获前面也无济于事,因为你仍然以任何方式写入向量的元素.
(请注意,我个人在平台上成功使用了这种确切的模式而没有遇到任何问题.)