我一直在学习多线程应用程序,尤其是关于如何使用MUTEX来防止比赛条件。但是,在编写一些代码时,我在代码中发现了种族条件(使用valgrind
的helgrind
工具),我相信一个线程中的执行可能会在解锁后和返回之前停止。
如果我们在下面进行示例代码,则在Mutex Unlock和返回语句之间是否可能存在竞赛条件?如果是这样,我们如何解决此问题?(缺乏要求呼叫者通过某种缓冲区并返回像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"需要全局的库函数的库中,但不能暴露于用户,返回值很重要。
这是当前代码中事件的顺序:
- 解锁锁。
- 读取共享的
x
变量。 - 返回您阅读的值。
x
的读取是完全未保护的。
您需要做的是
- 阅读共享的
x
变量。 - 解锁锁。
- 返回您阅读的值。
使读取受锁的保护。为此,请在解锁锁定之前将x
的值存储到Unshared(本地)变量,并将其用作返回值:
int retval = x;
pthread_mutex_unlock(&mutex);
return retval;