互斥锁是否足以保证线程安全操作?

3
假设我们有多个线程在增加一个共同的变量X,并且每个线程都使用互斥锁M进行同步;
function_thread_n(){

ACQUIRE (M)
X++;
RELEASE (M)

}

互斥锁确保只有一个线程在任何时候更新X,但是互斥锁是否确保一旦更新了X的值,其他线程也能看到它呢?假设X的初始值为2;线程1将其增加到3。然而,另一个处理器的缓存可能仍然具有较早的值2,另一个线程仍然可以将值2增加到3。缓存一致性的第三个条件仅要求不同处理器进行的写入顺序保持不变,对吗?

我想这就是内存屏障的作用,如果在释放互斥锁之前使用内存屏障,则可以避免此问题。

1个回答

2

这是一个很好的问题。
简而言之:短答案是“是的”。

Mutexes提供了三个主要服务:

  1. 互斥,确保在给定mutex的获取和释放之间只有一个线程在关键部分执行指令。
  2. 编译器优化栅栏,防止编译器的优化器在编译期间将load/store指令移出该关键部分。
  3. 适用于当前架构的体系结构内存屏障,通常包括在mutex获取期间进行内存获取栅栏指令,在mutex释放期间进行内存释放栅栏指令。这些栅栏防止超标量处理器在运行时有效地重新排序跨越栅栏的内存load/store,以使它们似乎是在关键部分之外“执行”的。

所有三者的组合确保由mutex获取/释放所界定的关键部分内的数据访问永远不会与另一个线程的数据访问发生竞争,后者也使用相同的mutex来保护其访问。

关于您问题中涉及缓存的部分,一致性缓存内存系统确保在任何特定时刻,给定的内存行只能被一个核心写入。此外,内存存储操作直到清除了缓存系统中其他核心的“新陈代谢”副本(例如其他核心的L1)才完成。有关更多详细信息,请参见this question

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接