pthread_mutex_lock是否在语义之前发生

时间:2015-07-21 14:20:47

标签: c++ multithreading synchronization happens-before

threadA浏览此代码段

{
    global_a = 100;  // 1
    {
        pthread_mutex_lock(&b_mutex)
                ...
        pthread_mutex_unlock(&b_mutex)
    }  // 2
}

threadB浏览此代码段

{
    {
        pthread_mutex_lock(&b_mutex)
                ...
        pthread_mutex_unlock(&b_mutex)
    }  // 3

    int tmp = global_a; // 4
}

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

  1. threadA --- 1
  2. threadA --- 2
  3. threadB --- 3
  4. threadB --- 4
  5. threadB "int tmp = global_a;"的代码能否看到"global_a = 100;"处设置的threadA?

    欢迎提出任何建议。

2 个答案:

答案 0 :(得分:1)

pthread_mutex_lock不会阻止以前的指令在其后面进行排序。

类似地,pthread_mutex_unlock不会阻止在其之前订购跟随指令。

可是:

  1. 在threadA global_a = 100 发生之前 pthread_mutex_unlock(&b_mutex)

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

  3. 如果你观察

      threadL中的
    1. pthread_mutex_unlock(&b_mutex) 在threadB中 pthread_mutex_lock(&b_mutex)之前发生。
    2. (换句话说,threadB在 threadA发布之后获取锁),然后

      threadA中的

      global_a = 100; 发生在threadB中的 int tmp = global_a;之前。所以,最后一个看到了第一个的效果。

      POSIX标准所说的内容:

      至于POSIX标准中的同步细节,我发现的唯一参考(以及其他参考)是关于Memory Synchronization的简短章节。它说pthread_mutex_lock(以及其他一些功能)

        

      使内存与其他线程同步

      有人将此解释为完全内存障碍保证,其他人(和我)更喜欢考虑一些经典保证,当锁定和等待动作提供内存获取时语义,解锁和通知 - 内存释放语义。例如,参见mail

      POSIX中没有发生在之前的术语。但它可以像往常一样定义,考虑到记忆顺序保证(在一个人的解释中)。

答案 1 :(得分:1)

如果可以保证执行顺序 - 当是的时候。如果您可以保证执行顺序,则甚至不需要锁定某些体系结构。

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

此外,您的编译器也可能会制造东西。因此,将变量声明为volatile。