c++线程:共享内存不更新,尽管没有竞争
C++ threads: shared memory not updated despite absence of race
我正在试验c++标准线程。我编写了一个小基准测试来测试性能开销和总体吞吐量。原理是在一个或几个线程中运行一个10亿次迭代的循环,不时地进行小暂停。
在第一个版本中,我在共享内存中使用计数器(即普通变量)。我期望得到以下输出:
Sequential 1e+009 loops 4703 ms 212630 loops/ms 2 thrds:t1 1e+009 loops 4734 ms 211238 loops/ms 2 thrds:t2 1e+009 loops 4734 ms 211238 loops/ms 2 thrds:tt 2e+009 loops 4734 ms 422476 loops/ms manythrd tn 1e+009 loops 7094 ms 140964 loops/ms ... manythrd tt 6e+009 loops 7094 ms 845785 loops/ms
不幸的是,显示显示了一些计数器,好像它们没有初始化!
我可以通过将每个计数器的结束值存储在atomic<>
中以供以后显示来解决这个问题。然而我不明白为什么基于简单共享内存的版本不能正常工作:每个线程使用自己的计数器,所以没有竞争条件。甚至显示线程也只有在计数线程完成后才能访问计数器。使用volatile
也没有帮助。
谁能解释我这个奇怪的行为(如果记忆没有更新),告诉我,如果我错过了什么?
这里是共享变量:
const int maxthread = 6;
atomic<bool> other_finished = false;
atomic<long> acounter[maxthread];
下面是线程函数的代码:
void foo(long& count, int ic, long maxcount)
{
count = 0;
while (count < maxcount) {
count++;
if (count % 10000000 == 0)
this_thread::sleep_for(chrono::microseconds(1));
}
other_finished = true; // atomic: announce work is finished
acounter[ic] = count; // atomic: share result
}
下面是我如何调用基准测试线程的一个例子:
mytimer.on(); // second run, two threadeds
thread t1(foo, counter[0], 0, maxcount); // additional thread
foo(counter[1], 1, maxcount); // main thread
t1.join(); // wait end of additional thread
perf = mytimer.off();
display_perf("2 thrds:t1", counter[0], perf); // non atomic version of code
display_perf("2 thrds:t2", counter[1], perf);
display_perf("2 thrds:tt", counter[0] + counter[1], perf);
下面是重现这个问题的简化版本:
void deep_thought(int& value) { value = 6 * 9; }
int main()
{
int answer = 42;
std::thread{deep_thought, answer).join();
return answer; // 42
}
看起来像是将对answer
的引用传递给工作函数,并将6 * 9
分配给引用,从而分配给answer
。但是,std::thread
的构造函数复制了answer
,并将对该副本的引用传递给worker函数,并且主线程中的变量answer
永远不会改变。
GCC-4.9和Clang-3.5都拒绝了上面的代码,因为工作函数不能用左值引用调用。您可以通过使用std::ref
:
std::thread{deep_thought, std::ref(answer)}.join();
相关文章:
- 从C++本机插件更新Vector3数组
- QGraphicsPolygonItem在拖动时未更新QPolygonF坐标
- cmake更新缓存的变量
- 更新到莫哈韦后出现cmath错误
- OpenMP:并行更新数组总是需要减少数组吗
- 为什么我的变量没有更新,我的 LED 没有亮起?
- 指针没有更新它在void函数内部指向的值
- 如何在c++中获取要更新的值
- 已修改的LinkedList未在文本文件本身中更新
- Qt:当QListView获得新条目时,如何更新QStringList
- 更新的矢量元素不打印
- 如何使用按钮更新GTK3图像以使用C++从相机捕获图片
- 如何在ECS框架中更新组件数据和通知系统
- 从VS 2015更新3更新到VS2015更新3 d后浮点计算行为不同的原因
- 如果我想在没有更新编译器的情况下使用新功能,该怎么办?
- compare_exchange C++函数如何确定竞争条件?
- 如何在 C++11 中查找和更新向量中的一个嵌套结构
- (SFML)按下键时,播放器构造函数未使用正确的动画进行更新
- 在 emscripten 网页汇编正在运行期间更新进度条?
- c++线程:共享内存不更新,尽管没有竞争