互斥锁解锁和从函数返回之间是否会出现竞争条件

Can a race condition occur between mutex unlocking and returning from function

我一直在学习多线程应用程序,尤其是如何使用互斥锁来防止竞争条件。然而,在编写一些代码时,我在我的代码中发现了一个竞争条件(使用 valgrind 中的 helgrind 工具),我相信一个线程中的执行可能在解锁之后和 return.

如果我们采用下面的示例代码,互斥锁解锁和 return 语句之间是否可能存在竞争条件?如果是这样,我们如何解决这个问题?(除了要求调用者传入某种缓冲区和 returning 一个常量值,如 0

#include <pthread.h>

int x = 0;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

doSomething()
{
    pthread_mutex_lock(&mutex);
    ++x;
    pthread_mutex_unlock(&mutex);
               /* <-- Race Condition? */
    return x;
}

void *t2()
{
    doSomething();
}

main()
{
    pthread_t thread;
    pthread_t_create(&thread, NULL);
    doSomething();
    pthread_join(thread, NULL);
    return 0;
}

注意: 我明白在上面的例子中,returning 'x' 是没用的,因为 x 是全局的。但是,在库函数中 'x' 需要全局但不能向用户公开的库中,return 值变得很重要。

这是您当前代码中的事件顺序:

  1. 解开锁。
  2. 读取共享的 x 变量。
  3. Return您读取的值。

x 的读取完全不受保护。

你需要做的是

  1. 读取共享的 x 变量。
  2. 解开锁。
  3. Return您读取的值。

这样读就受到了锁的保护。为此,在解锁之前将 x 的值存储到非共享(本地)变量,并将其用作 return 值:

int retval = x;
pthread_mutex_unlock(&mutex);
return retval;