creating/joining 个线程时的隐式同步
Implicit synchronization when creating/joining threads
考虑到 creating/joining 线程时隐含的同步,x
的类型需要什么 最小 框架才能使此代码工作:std::atomic
? volatile
?什么都没有?
#include <thread>
#include <cassert>
int main() {
int x = 123; // ***
std::thread( [ & ] { assert( x == 123 ); x = 321; } ).join();
assert( x == 321 );
return 0;
}
std::thread
的构造函数的调用是同步的,并且发生在调用线程函数副本 (30.3.1.2/6) 之前。
thread::join
给出了类似的同步保证:线程的完成发生在 join
returns (30.3.1.4/7).
之前
您的代码创建了一个线程并立即加入它。尽管您的 lambda 通过引用捕获,但没有并发性(代码运行就像顺序一样),并且 std::thread
提供的保证确保您不需要任何特殊的框架来保护 x
。断言永远不会失败。
假设您的代码片段不同,因此您实际上有某种并发访问,您将不得不使用 std::atomic
或互斥体。 volatile
绝对不够(巧合除外)。
考虑到 creating/joining 线程时隐含的同步,x
的类型需要什么 最小 框架才能使此代码工作:std::atomic
? volatile
?什么都没有?
#include <thread>
#include <cassert>
int main() {
int x = 123; // ***
std::thread( [ & ] { assert( x == 123 ); x = 321; } ).join();
assert( x == 321 );
return 0;
}
std::thread
的构造函数的调用是同步的,并且发生在调用线程函数副本 (30.3.1.2/6) 之前。
thread::join
给出了类似的同步保证:线程的完成发生在 join
returns (30.3.1.4/7).
您的代码创建了一个线程并立即加入它。尽管您的 lambda 通过引用捕获,但没有并发性(代码运行就像顺序一样),并且 std::thread
提供的保证确保您不需要任何特殊的框架来保护 x
。断言永远不会失败。
假设您的代码片段不同,因此您实际上有某种并发访问,您将不得不使用 std::atomic
或互斥体。 volatile
绝对不够(巧合除外)。