我在 C++ 中使用自定义的协程实现(编译器 g++,在 ARM 上)。协程可能会通过调用 move_to_thread 函数(或其他方式,但这会让我明白我的观点)从一个线程迁移到另一个线程。我过于简单化了,但它有点像这样:
__thread int x = 0;
void f() {
x = 5;
// do some more work on current thread (thread 1, say)
move_to_thread(2);
// do more work, now on thread 2
int y = x; // with optimization, I'm getting the wrong x
}
我遇到的问题是调用 move_to_thread 之前和之后完成的工作使用线程局部变量(使用__thread
)。使用优化编译时,线程 2 上运行的代码仍然访问线程 1 的线程局部变量,而不是它自己的变量。这是因为对线程局部变量的访问会执行以下操作:
- 查找当前线程的 TLS 线程指针
- 将 x 的 TLS 偏移量添加到线程指针
- 将此地址的内存用作 x
但是,启用优化后,(1) 和可能 (2) 正在针对第二次访问进行优化,因为编译器假定开始在特定线程上运行的函数将保留在该线程上。这个假设不适用于我的代码。
如何让编译器在调用 move_to_thread 之前和之后查看正确的线程本地存储,而不完全取消优化?