互斥锁解锁和从函数返回之间是否会出现竞争条件
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 值变得很重要。
这是您当前代码中的事件顺序:
- 解开锁。
- 读取共享的
x
变量。
- Return您读取的值。
x
的读取完全不受保护。
你需要做的是
- 读取共享的
x
变量。
- 解开锁。
- Return您读取的值。
这样读就受到了锁的保护。为此,在解锁之前将 x
的值存储到非共享(本地)变量,并将其用作 return 值:
int retval = x;
pthread_mutex_unlock(&mutex);
return retval;
我一直在学习多线程应用程序,尤其是如何使用互斥锁来防止竞争条件。然而,在编写一些代码时,我在我的代码中发现了一个竞争条件(使用 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 值变得很重要。
这是您当前代码中的事件顺序:
- 解开锁。
- 读取共享的
x
变量。 - Return您读取的值。
x
的读取完全不受保护。
你需要做的是
- 读取共享的
x
变量。 - 解开锁。
- Return您读取的值。
这样读就受到了锁的保护。为此,在解锁之前将 x
的值存储到非共享(本地)变量,并将其用作 return 值:
int retval = x;
pthread_mutex_unlock(&mutex);
return retval;