松弛的内存顺序效果是否可以扩展到执行线程的生命周期之后?
Does relaxed memory order effect can be extended to after performing-thread's life?
假设在c++ 11程序中,我们有一个名为 a 的主线程,它启动一个名为B的异步线程。在线程B中,我们以std::memory_order_relaxed
内存顺序对原子变量执行原子存储。线程A与线程B连接。然后线程A启动另一个名为C的线程,该线程执行具有std::memory_order_relaxed
内存顺序的原子加载操作。线程C加载的内容是否可能与线程B写入的内容不同?换句话说,松弛的内存一致性是否延伸到线程的生命周期之后?
#include <atomic>
#include <iostream>
#include <future>
int main() {
static const int nTests = 100000;
std::atomic<int> myAtomic( 0 );
auto storeFunc = [&]( int inNum ){
myAtomic.store( inNum, std::memory_order_relaxed );
};
auto loadFunc = [&]() {
return myAtomic.load( std::memory_order_relaxed );
};
for( int ttt = 1; ttt <= nTests; ++ttt ) {
auto writingThread = std::async( std::launch::async, storeFunc, ttt );
writingThread.get();
auto readingThread = std::async( std::launch::async, loadFunc );
auto readVal = readingThread.get();
if( readVal != ttt ) {
std::cout << "mismatch!t" << ttt << "t!=t" << readVal << "n";
return 1;
}
}
std::cout << "done.n";
return 0;
}
在可移植线程平台通常为您提供指定内存可见性或设置显式内存屏障的能力之前,可移植同步只能通过显式同步(如互锁)和隐式同步来完成。
通常,在创建线程之前,设置一些数据结构,线程将在启动时访问这些数据结构。为了避免仅仅为了实现这种常见模式而使用互斥锁,线程创建被定义为隐式同步事件。同样常见的是连接一个线程,然后查看它计算的一些结果。同样,为了避免仅仅为了实现这种通用模式而使用互斥锁,将连接线程定义为隐式同步事件。
由于线程的创建和结构被定义为同步操作,因此连接线程必须在线程终止后进行。因此,您将看到在线程终止之前发生的任何必要的。更改一些变量然后创建线程的代码也是如此——新线程必须看到在创建之前发生的所有更改。线程创建或终止时的同步就像互斥锁上的同步。同步操作创建了这种排序关系,以确保内存可见性。
正如SergeyA所提到的,你绝对不应该试图通过测试来证明多线程世界中的某些东西。当然,如果一个测试失败了,那就证明你不能依赖你所测试的东西。但是,即使一个测试通过了你所能想到的所有测试方法,这并不意味着它不会在你没有测试过的平台、CPU或库上失败。你永远不能通过这种测试来证明这样的事情是可靠的。
如果您想测试这样的东西,您可以使用模型检查器来探索测试用例的所有可能的执行(受到一些深奥的限制)。
见http://plrg.eecs.uci.edu/c11modelchecker.html
- 当我在其中一个线程执行中(在activemq-cpp中)捕获到特定值时,我如何终止/停止所有其他线程
- C++线程:如何在一个线程仍在运行时阻止另一个线程执行 (Win32)
- 在给定时间段内,线程执行的指令数量是否有最小数量?
- 如何在C++中停止线程执行
- 为什么Win API线程执行函数,而标准线程则没有
- 线程执行在IDE中和C 中的EXE应用程序中是否有所不同
- 从线程执行的函数中返回结构数组
- 为什么在从线程执行方法时使用QMetaObject::invokeMethod
- 只有一个线程执行 CUDA 内核
- C++ 多线程:执行顺序
- async_connect()超时,多个线程执行io_service.run()
- 是否可以将线程执行转移到另一个线程?
- 具有随机数总和的多线程执行时间
- 如何 在没有 Boost 的情况下将 C++ 成员函数作为线程执行
- openMP 在自定义容器中从 2 到 4 个线程执行二进制搜索时速度变慢
- 如何使生成的线程拖延足够长的时间以使生成线程执行某些操作
- 远程线程执行
- C++中的基本多线程(执行顺序)
- 线程池中的C++线程执行顺序
- 锁定由不同线程执行的多个函数