pthread_mutex_lock 是不是有happens-before语义
Posted
技术标签:
【中文标题】pthread_mutex_lock 是不是有happens-before语义【英文标题】:Does pthread_mutex_lock have happens-before semanticspthread_mutex_lock 是否有happens-before语义 【发布时间】:2015-07-21 14:20:47 【问题描述】:threadA通过这个sn-p
global_a = 100; // 1
pthread_mutex_lock(&b_mutex)
...
pthread_mutex_unlock(&b_mutex)
// 2
threadB经过这个sn-p
pthread_mutex_lock(&b_mutex)
...
pthread_mutex_unlock(&b_mutex)
// 3
int tmp = global_a; // 4
并假设从观察者的角度来看,执行顺序确实是
-
线程A --- 1
线程A --- 2
线程B --- 3
线程B --- 4
threadB "int tmp = global_a;"
的代码可以看到 "global_a = 100;"
的 threadA 设置了什么吗?
欢迎提出任何建议。
【问题讨论】:
【参考方案1】:pthread_mutex_lock
不会阻止 previous 指令在它之后排序。
类似地,pthread_mutex_unlock
不会阻止 followed 指令在它之前排序。
但是:
在线程A中global_a = 100
之前发生 pthread_mutex_unlock(&b_mutex)
。
在线程 B pthread_mutex_lock(&b_mutex)
之前发生 int tmp = global_a;
。
如果你观察
pthread_mutex_unlock(&b_mutex)
在线程A 之前发生 pthread_mutex_lock(&b_mutex)
在线程B。
(换句话说,线程B在线程A释放它之后获取锁),然后
global_a = 100;
在线程A 之前发生 int tmp = global_a;
在线程B。所以,最后一个看到第一个的效果。
POSIX 标准是怎么说的:
关于 POSIX 标准中的同步细节,我找到的唯一参考(以及其他参考)是关于 Memory Synchronization 的简短章节。它说pthread_mutex_lock
(和其他一些功能)
相对于其他线程同步内存
有人将此解释为 完全内存屏障 保证,其他人(和我)更喜欢考虑一些 经典 保证,当锁定和等待操作提供 内存获取 语义,解锁和通知 - 内存释放 语义。参见,例如,这个mail。
POSIX 中没有 happens-before 术语。但它可以像往常一样定义,考虑到内存顺序保证(在一个人的解释中)。
【讨论】:
证明很好,但是 happens-before 和 happens-before 的 transitiviy 的定义在哪里与pthread_mutex_lock
和pthread_mutex_unlock
?我有谷歌它,但没有。你能给我一些关于它的参考吗?
我在答案中添加了一些参考资料。 POSIX 没有定义 happens-before 术语,但可以根据内存顺序保证来定义。【参考方案2】:
如果你能保证执行顺序——当是。如果你能保证执行顺序,你甚至不需要在某些架构上加锁。
Lock 实际上做了三件事: 1. 不允许不同的代码同时执行。看。这里没有提到内存。它只是保证不同线程中的代码不会同时执行。 2. 在某些架构上,它会插入缓存一致性指令。这迫使多个处理器系统将数据刷新到真实内存中。但是您现在不应该担心这种情况,因为“如果对同一内存位置的所有写入都以某种顺序执行,则多处理器是缓存一致的” 3. 插入内存屏障指令。它是针对处理器的,告诉它不要弄乱执行顺序。
你的编译器也可能会刹车。因此,将您的变量声明为 volatile。
【讨论】:
最后加上“所以将你的变量声明为 volatile。”,你的意思是也许 threadB “int tmp = global_a;” 无法查看“global_a = 100;”处的线程A设置了什么以上是关于pthread_mutex_lock 是不是有happens-before语义的主要内容,如果未能解决你的问题,请参考以下文章
pthread_join 和 pthread_mutex_lock 有啥区别?