【问题标题】: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
}

并假设从观察者的角度来看,执行顺序确实是

  1. 线程A --- 1
  2. 线程A --- 2
  3. 线程B --- 3
  4. 线程B --- 4

threadB "int tmp = global_a;" 的代码可以看到 "global_a = 100;" 的 threadA 设置了什么吗?

欢迎提出任何建议。

【问题讨论】:

    标签: c++ multithreading synchronization happens-before


    【解决方案1】:

    pthread_mutex_lock 不会阻止 previous 指令在它之后排序。

    类似地,pthread_mutex_unlock 不会阻止 followed 指令在它之前排序。

    但是:

    1. 在线程A中global_a = 100 之前发生 pthread_mutex_unlock(&b_mutex)

    2. 在线程 B pthread_mutex_lock(&b_mutex) 之前发生 int tmp = global_a;

    如果你观察

    1. 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-beforehappens-beforetransitiviy 的定义在哪里与pthread_mutex_lockpthread_mutex_unlock?我有谷歌它,但没有。你能给我一些关于它的参考吗?
    • 我在答案中添加了一些参考资料。 POSIX 没有定义 happens-before 术语,但可以根据内存顺序保证来定义。
    【解决方案2】:

    如果你能保证执行顺序——当是。如果你能保证执行顺序,你甚至不需要在某些架构上加锁。

    Lock 实际上做了三件事: 1. 不允许不同的代码同时执行。看。这里没有提到内存。它只是保证不同线程中的代码不会同时执行。 2. 在某些架构上,它会插入缓存一致性指令。这迫使多个处理器系统将数据刷新到真实内存中。但是您现在不应该担心这种情况,因为“如果对同一内存位置的所有写入都以某种顺序执行,则多处理器是缓存一致的” 3. 插入内存​​屏障指令。它是针对处理器的,告诉它不要弄乱执行顺序。

    你的编译器也可能会刹车。因此,将您的变量声明为 volatile。

    【讨论】:

    • 最后加上“所以将你的变量声明为 volatile。”,你的意思是也许 threadB “int tmp = global_a;” 无法查看“global_a = 100;”处的线程A设置了什么
    猜你喜欢
    • 2011-05-25
    • 2018-04-13
    • 1970-01-01
    • 1970-01-01
    • 2014-02-04
    • 2019-06-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多