【发布时间】:2020-03-22 07:44:14
【问题描述】:
我认为在线程内以这种方式更新原子值并不好(总和有时看起来不太好)
std::atomic<double> e(0);
auto worker = [&] (size_t begin, size_t end, std::atomic<double> & acc) {
double ee = 0;
for(auto k = begin; k != end; ++k) {
ee += something[k];
}
acc.store( acc.load() + ee );
};
std::vector<std::thread> threads(nbThreads);
const size_t grainsize = miniBatchSize / nbThreads;
size_t work_iter = 0;
for(auto it = std::begin(threads); it != std::end(threads) - 1; ++it) {
*it = std::thread(worker, work_iter, work_iter + grainsize, std::ref(e));
work_iter += grainsize;
}
threads.back() = std::thread(worker, work_iter, miniBatchSize, std::ref(e));
for(auto&& i : threads) {
i.join();
}
虽然使用锁保护似乎没问题
std::atomic<double> e(0);
std::mutex m;
auto worker = [&] (size_t begin, size_t end, std::atomic<double> & acc) {
double ee = 0;
for(auto k = begin; k != end; ++k) {
ee += something[k];
}
{
const std::lock_guard<std::mutex> lock(m);
acc.store( acc.load() + ee );
}
};
std::vector<std::thread> threads(nbThreads);
const size_t grainsize = miniBatchSize / nbThreads;
size_t work_iter = 0;
for(auto it = std::begin(threads); it != std::end(threads) - 1; ++it) {
*it = std::thread(worker, work_iter, work_iter + grainsize, std::ref(e));
work_iter += grainsize;
}
threads.back() = std::thread(worker, work_iter, miniBatchSize, std::ref(e));
for(auto&& i : threads) {
i.join();
}
我是对的,我在这里缺少什么?是 std::ref(e) 的问题吗?
【问题讨论】:
标签: c++ c++11 lambda thread-safety