我有一个多线程应用程序,其中每个线程都有一个整数类型的变量。这些变量在程序执行期间递增。在代码中的某些点,线程将其计数变量与其他线程的计数变量进行比较。
现在,我们知道在多核上运行的线程可能无序执行,线程可能无法读取其他线程的预期计数器值。要解决这个问题,一种方法是使用原子变量,例如std :: atomic<> C ++ 11但是,在每个计数器增量处执行内存栅栏将大大减慢程序的速度。
现在我想要做的是,当一个线程即将读取其他线程的计数器时,只有这样才会创建一个内存栅栏,并在该点内存更新所有线程的计数器。如何在C ++中完成。我正在使用Linux和g ++。
答案 0 :(得分:4)
C ++ 11标准库包含对<atomic>
std::atomic_thread_fence
中围栏的支持。
调用此方法会调用完整的栅栏:
std::atomic_thread_fence(std::memory_order_seq_cst);
如果您只想发布获取或仅发布版本围栏,则可以使用std:memory_order_acquire
和std::memory_order_release
代替。
答案 1 :(得分:1)
x86内在函数对应于您可以自己使用的内存屏障。 Windows标头有一个内存屏障宏,因此您应该能够找到与Linux等效的内容。
答案 2 :(得分:0)
我的建议是在更高级别的类中有一个collectTimers()函数,可以向每个线程询问其计数器(通过queue / msg)。这样更新计时器不会延迟,但收集计时器会慢一些。
只有在线程之间有某种通信机制时,这才有效。
答案 3 :(得分:0)
为什么不拥有一个“控制”线程,每个线程向谁报告其计数器增量并询问其他人的值?
这将使它非常有效和简单。只是一个建议。
答案 4 :(得分:0)
您可以尝试使用http://mirror.nexcess.net/kernel.org/linux/kernel/people/paulmck/perfbook/perfbook.2011.08.28a.pdf
的Secion 4.4.3中的信号窃取限制计数器设计这种设计可以消除快速路径中的原子操作(递增每线程计数器)。当然,复杂性是否值得由你来决定。
答案 5 :(得分:-1)
您可以将boost :: asio :: strand用于此目的。创建一个负责读取计数器的处理程序。可以从多个线程调用该处理程序。而不是直接调用处理程序,将其包装在boost :: asio :: strand中。这将确保多个线程不能同时调用处理程序。
http://www.boost.org/doc/libs/1_35_0/doc/html/boost_asio/tutorial/tuttimer5.html
我希望我能正确理解这个问题。