【发布时间】:2016-12-10 22:51:54
【问题描述】:
我一直在尝试学习 pthreads,使用 mutex 和 cond,但我不知道如何仅在使用它的最后一个线程不再需要它之后重置变量。
我有以下代码:
int i = 0;
pthread_mutex_t mutex;
pthread_cond_t cond;
int test() {
if (i == 0) {
pthread_mutex_init(&mutex, NULL);
pthread_cond_init(&cond, NULL);
}
pthread_mutex_lock(&mutex);
++i;
if (i % 5 != 0) {
pthread_cond_wait(&cond, &mutex);
}
else {
pthread_cond_broadcast(&cond);
}
int j = i;
i = 0; /* problem line */
pthread_mutex_unlock(&mutex);
//i = 0; /* tried here too */
return j;
}
我有多个线程调用这个test() 方法。
前4个线程会一直等到第5个被调用,然后所有5个线程都会返回5。但是 6th+ 会返回 '6','7',... 等等,我想重置 i 变量i = 0,所以计数会重新开始。
我想再做一个 thread_cond_t 让线程等到所有 j = i 完成。但我认为这是不对的(或至少是不必要的)。
实际输出是(由于线程,顺序未定):
0
0
0
0
5
0
0
0
5
我希望他们都是5s。
编辑:我将j 设为全局,i 在广播后进行了修改,到目前为止它一直有效:
int i = 0, j;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
int test() {
pthread_mutex_lock(&mutex);
++i;
if (i % 5 != 0) {
pthread_cond_wait(&cond, &mutex);
} else {
pthread_cond_broadcast(&cond);
j = i;
}
i = 0;
pthread_mutex_unlock(&mutex);
return j;
}
此代码在达到 5 后成功重置变量,并在所有线程上打印该值,但是当我尝试多个线程时,我似乎遇到了数据争用。
【问题讨论】:
-
你确定第一个线程可以在第二个线程启动前调用2个init函数、锁和增量吗?
-
实际上,我也有同样的疑问,但无法猜测另一种方法来初始化 mutex 和 cond 一次,到目前为止我还没有遇到过问题(多次尝试代码),但是欢迎提供见解。
-
可以在启动线程之前调用init函数吗?你也可以使用初始化器
PTHREAD_MUTEX_INITIALIZER。其余的代码看起来没问题。您可能会两次初始化互斥锁,从而调用未定义的行为。 -
我无法在启动线程之前初始化 init() 函数,另一个函数(不可编辑)直接调用
test()方法。如您所说,将尝试 mutex_initializer 。谢谢。 -
@JonathanLeffler 你是对的,我已经更改了代码,现在将编辑我的帖子。现在它按预期工作,感谢 mch 和 JonathanLeffer。我有一个新问题 ;(,当我测试大量线程时它失败了,似乎我有数据竞争问题,我不确定如何解决它。