pthread多线程学习笔记五条件变量4使用之signal只能唤醒当前处于wait的线程

直奔主题,如果signal的时候没有线程在条件等待队列里,那么本次signal就没有效果,后续的线程进入条件队列之后,无法被之前的signal唤醒。

似乎这与Windows上不一样?

考虑一个情形,旅客在出租车点排队(进入wait队列),当有出租车到来时,鸣笛或者干啥的(总之就是signal),旅客上车。

于是有了下面这个例子:

#include <stdio.h>

#include <pthread.h>

pthread_cond_t taxiCond;

pthread_mutex_t taxiMutex;

void *travelerArrive(void *name)

{

printf("Traveler: %s need a taxi now!\n",(char*)name);

pthread_mutex_lock(&taxiMutex);

pthread_cond_wait(&taxiCond, &taxiMutex);

pthread_mutex_unlock(&taxiMutex);

printf("Traveler: %s now got a taxi!\n",(char*)name);

pthread_exit((void*)0);

}

void *taxiArrive(void *name)

{

printf("Taxi %s arrives\n",(char*)name);

pthread_cond_signal(&taxiCond);

pthread_exit((void*)0);

}

int main()

{

pthread_t thread;

pthread_attr_t threadAttr;

pthread_attr_init(&threadAttr);

pthread_cond_init(&taxiCond,NULL);

/*pthread_create(&thread, &threadAttr, travelerArrive, (void*)("Liona"));*/

/*sleep(1);*/

pthread_create(&thread, &threadAttr, taxiArrive, (void*)("Jack"));

sleep(1);

pthread_create(&thread, &threadAttr, travelerArrive, (void*)("Susan"));

sleep(1);

pthread_create(&thread, &threadAttr, taxiArrive, (void*)("Mike"));

sleep(1);

return 0;

}

当Jack出租车到达后,signal,实际上没有效果。

当Susan到了后,进入wait队列,是收不到哦啊Jack的signal的。

只有当Mike出租车到了后,signal,Susan收到。

程序输出:

Taxi Jack arrives

Traveler: Susan need a taxi now!

Taxi Mike arrives

Traveler: Susan now got a taxi!

如果觉得这样不合理,其实容易改变,加一个关于旅客人数的全局变量即可,修改后的程序如下:

#include <stdio.h>

#include <pthread.h>

pthread_cond_t taxiCond;

pthread_mutex_t taxiMutex;

int travelerCount = 0;

void *travelerArrive(void *name)

{

printf("Traveler: %s need a taxi now!\n",(char*)name);

pthread_mutex_lock(&taxiMutex);

travelerCount++;

pthread_cond_wait(&taxiCond, &taxiMutex);

travelerCount--;

pthread_mutex_unlock(&taxiMutex);

printf("Traveler: %s now got a taxi!\n",(char*)name);

pthread_exit((void*)0);

}

void *taxiArrive(void *name)

{

printf("Taxi %s arrives\n",(char*)name);

while (1) {

pthread_mutex_lock(&taxiMutex);

if (travelerCount>0) {

pthread_cond_signal(&taxiCond);

pthread_mutex_unlock(&taxiMutex);

break;

}

pthread_mutex_unlock(&taxiMutex);

}

pthread_exit((void*)0);

}

int main()

{

pthread_t thread;

pthread_attr_t threadAttr;

pthread_attr_init(&threadAttr);

pthread_cond_init(&taxiCond,NULL);

/*pthread_create(&thread, &threadAttr, travelerArrive, (void*)("Liona"));*/

/*sleep(1);*/

pthread_create(&thread, &threadAttr, taxiArrive, (void*)("Jack"));

sleep(1);

pthread_create(&thread, &threadAttr, taxiArrive, (void*)("Join"));

sleep(1);

pthread_create(&thread, &threadAttr, travelerArrive, (void*)("Susan"));

sleep(1);

pthread_create(&thread, &threadAttr, taxiArrive, (void*)("Mike"));

sleep(1);

pthread_create(&thread, &threadAttr, travelerArrive, (void*)("Lyn"));

sleep(1);

return 0;

}