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

标签 c multithreading mutex

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

如果我们采用下面的示例代码,在互斥锁解锁和返回语句之间是否可能存在竞争条件?如果是这样,我们如何解决这个问题?(除了要求调用者传入某种缓冲区并返回一个常量值,如 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;
}

注意:我明白在上面的例子中,返回 'x' 是没有用的,因为 x 是全局的。但是,在“x”对于库函数而言需要全局但又不能向用户公开的库中,返回值变得很重要。

最佳答案

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

  1. 打开锁。
  2. 读取共享的 x 变量。
  3. 返回您读取的值。

x 的读取完全不 protected 。

你需要做的是

  1. 读取共享的 x 变量。
  2. 打开锁。
  3. 返回您读取的值。

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

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

关于互斥锁解锁和从函数返回之间是否会出现竞争条件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41153505/

相关文章:

c - dladdr 不返回函数名

c - 我需要在不破坏我的加密算法的情况下格式化我的输出

iphone - 将 NSOperation 添加到 NSOperationQueue 时出现 EXC_BAD_ACCESS

java - OrientDB连接池

c - 如何使用 malloc 为非指针对象(例如互斥锁)分配空间?

由于互斥体,C++ vector 删除迭代器超出范围

c - 替换 switch case 中的 goto

c - E Balaguruswamy 书第 1 章主题子例程第 3 版中的 C 代码错误

c# - 为什么锁对象必须是只读的?

c - 使用没有互斥锁的线程增加全局变量会奇怪地返回正确的值