3

我有一些使用线程本地存储的 C++ 代码,每个线程都有一个可以将数据推入的向量。

我使用 TLS 存储每个线程的索引 ID,这可用于查找将数据推送到哪个向量。然后它执行大量代码,将数据推送到向量中。

我想知道的是,操作系统是否有可能在获取指向线程本地对象的指针后重新安排我的代码在不同的线程上执行。(到目前为止,代码执行得很好,我还没有看到这种情况发生)。但是如果可能的话,这似乎肯定会破坏我的程序,因为现在两个线程可以拥有相同的对象。

假设这是真的,即使对于使用任何复杂性 TLS 的任何代码,这似乎也是一个问题,TLS 是否仅适用于您不获取地址的简单对象?

谢谢!

4

2 回答 2

3

线程本地存储就是这样 - 每个线程的存储。每个线程都有自己的私有数据结构。该线程,无论它在哪个处理器上运行,都是同一个线程。操作系统不会在线程内安排工作,它会安排哪些线程运行。

线程本地存储是通过具有某种间接性来完成的,这种间接性会随着线程本身而改变。有几种方法可以做到这一点,例如,操作系统可能在进程中从虚拟内存开始的特定偏移量处具有特定页面,并且当调度线程时,更新页表以匹配线程。

在 x86 处理器中,FS 或 GS​​ 通常用于“每线程”数据,因此操作系统将切换 FS 寄存器 [或在 64 位处理器的情况下寄存器的基地址内容]。读取 TLS 时,编译器将使用 FS 或 GS​​ 段寄存器作为内存读/写操作的前缀,因此您始终获得“您的私有数据”,而不是其他一些线程。

当然,操作系统可能有错误,但这是相当多的东西会依赖的东西,所以如果它坏了,它很快就会出现(除非它非常微妙,而且你必须站在正确的地方,用月亮在正确的相位,穿着正确的颜色衣服,风在正确的方向,日期可以被 3 和 7 整除,等等)。

于 2013-01-24T11:48:38.163 回答
2

TLS 表示 thread local,根据您的描述,每个线程通过 TLS 访问一个共享的向量向量(我不确定),您应该使用某种锁。任何示例代码?

于 2013-01-24T11:47:24.553 回答