2线程的pthread_cond_wait

我试图为2线程实现pthread_cond_wait 。 我的testing代码试图使用两个线程来预制以下场景:

  • 线程B等待条件
  • 线程五次打印“Hello”
  • 线程A信号线程B
  • 线程A等待
  • 线程B打印“再见”
  • 线程B信号线程A
  • 循环开始(x5)

到目前为止,代码打印了“Hello”五次,然后卡住了。 从我看过的例子来看,似乎我在正确的轨道上,“locking互斥锁,等待,获得其他线程的信号,解锁互斥量,做东西,循环”

testing代码:

 //Import #include <stdio.h> #include <stdlib.h> #include <pthread.h> #include <unistd.h> //global variables pthread_cond_t condA = PTHREAD_COND_INITIALIZER; pthread_cond_t condB = PTHREAD_COND_INITIALIZER; pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; void *threadA() { int i = 0, rValue, loopNum; while(i<5) { //unlock mutex rValue = pthread_mutex_unlock(&mutex); //do stuff for(loopNum = 1; loopNum <= 5; loopNum++) printf("Hello %d\n", loopNum); //signal condition of thread b rValue = pthread_cond_signal(&condB); //lock mutex rValue = pthread_mutex_lock(&mutex); //wait for turn while( pthread_cond_wait(&condA, &mutex) != 0 ) i++; } } void *threadB() { int n = 0, rValue; while(n<5) { //lock mutex rValue = pthread_mutex_lock(&mutex); //wait for turn while( pthread_cond_wait(&condB, &mutex) != 0 ) //unlock mutex rValue = pthread_mutex_unlock(&mutex); //do stuff printf("Goodbye"); //signal condition a rValue = pthread_cond_signal(&condA); n++; } } int main(int argc, char *argv[]) { //create our threads pthread_t a, b; pthread_create(&a, NULL, threadA, NULL); pthread_create(&b, NULL, threadB, NULL); pthread_join(a, NULL); pthread_join(b,NULL); } 

一个指针在正确的方向将不胜感激,谢谢! (在Linux上使用“gcc timeTest.c -o timeTest -lpthread”编译的代码)

Solutions Collecting From Web of "2线程的pthread_cond_wait"

你有两个问题。 首先是你没有使用while()循环正确 – 例如,在这里:

 //wait for turn while( pthread_cond_wait(&condA, &mutex) != 0 ) i++; 

while循环的主体是语句i++ – 这将执行pthread_cond_wait()i++直到pthread_cond_wait()返回一个错误,所以这实际上是一个无限循环。

第二个是你不能自己使用一个pthreads条件变量 – 它需要与一些实际的共享状态(最简单的,这个共享状态可能只是一个被互斥锁保护的标志变量)配对。 pthread_cond_wait()函数用于等待共享状态达到某个值,并且在线程更改共享状态时使用pthread_cond_signal()函数。 重做你的例子来使用这样一个变量:

 //global variables /* STATE_A = THREAD A runs next, STATE_B = THREAD B runs next */ enum { STATE_A, STATE_B } state = STATE_A; pthread_cond_t condA = PTHREAD_COND_INITIALIZER; pthread_cond_t condB = PTHREAD_COND_INITIALIZER; pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; void *threadA() { int i = 0, rValue, loopNum; while(i<5) { /* Wait for state A */ pthread_mutex_lock(&mutex); while (state != STATE_A) pthread_cond_wait(&condA, &mutex); pthread_mutex_unlock(&mutex); //do stuff for(loopNum = 1; loopNum <= 5; loopNum++) printf("Hello %d\n", loopNum); /* Set state to B and wake up thread B */ pthread_mutex_lock(&mutex); state = STATE_B; pthread_cond_signal(&condB); pthread_mutex_unlock(&mutex); i++; } return 0; } void *threadB() { int n = 0, rValue; while(n<5) { /* Wait for state B */ pthread_mutex_lock(&mutex); while (state != STATE_B) pthread_cond_wait(&condB, &mutex); pthread_mutex_unlock(&mutex); //do stuff printf("Goodbye\n"); /* Set state to A and wake up thread A */ pthread_mutex_lock(&mutex); state = STATE_A; pthread_cond_signal(&condA); pthread_mutex_unlock(&mutex); n++; } return 0; } 

请注意,在这里不需要使用两个条件变量condAcondB – 如果只使用一个条件变量,则代码将是正确的。

当你在while循环中添加花括号时,代码实际上在我的机器上工作得很好。

添加到caf所说的,当threadA在已经发送了condB信号之后启动threadB时,你将进入一个无限循环,因此为什么你需要在你的while循环中使用共享状态。

你可以在第47行使用usleep(1)引入人工延迟,然后自己去看看。