1.什么是条件变量
- 当一个线程互斥地访问某个变量的时候,它可能发现在其它线程改变状态之前,它什么也做不了
- 例如一个线程访问队列时,发现对列为空,它只能等待,直到其它线程将一个节点添加到队列中。这种情况就需要条件变量。
2.条件变量函数
pthread_cond_init //初始化
pthread_cond_destroy //销毁
pthread_cond_wait //在一个条件之上等待
pthread_cond_signal //条件满足时向一个等待线程发起通知
pthread_cond_broadcast //向等待的所有线程发起通知
3.条件变量使用规范
- 等待条件代码
pthread_mutex_lock(&mutex);
while (条件为假)//不用if是pthread_cond_wait可能被虚假唤醒
pthread_cond_wait(cond, mutex);
修改条件
pthread_mutex_unlock(&mutex);
- 给条件发送信号代码
pthread_mutex_lock(&mutex);
设置条件为真
pthread_cond_signal (cond);
pthread_mutex_unlock(&mutex);
4.条件变量解决生产者与消费者问题
#include <unistd.h>
#include <sys/types.h>
#include <pthread.h>
#include <semaphore.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#define ERR_EXIT(m) \
do \
{ \
perror(m); \
exit(EXIT_FAILURE); \
} while (0);
#define CONSUMERS_COUNT 2
#define PRODUCERS_COUNT 1
pthread_mutex_t g_mutex;
pthread_cond_t g_cond;
pthread_t g_thread[CONSUMERS_COUNT + PRODUCERS_COUNT];
int nready = 0; //当前缓冲区产品个数
void* consume(void *arg)
{
int num = *((int*)(&arg));
while (1)
{
pthread_mutex_lock(&g_mutex);
while (nready == 0)
{
printf("%d begin wait a condition ...\n", num);
pthread_cond_wait(&g_cond, &g_mutex); //对g_mutex进行解锁操作,才能让其它线程对nready进行修改
}
printf("%d end wait a condition ...\n", num);
printf("%d begin consume product ...\n", num);
--nready;
printf("%d end consume product ...\n", num);
pthread_mutex_unlock(&g_mutex);
sleep(1);
}
return NULL;
}
void* produce(void *arg)
{
int num = *((int*)(&arg));
while (1)
{
pthread_mutex_lock(&g_mutex);
printf("%d begin produce product ...\n", num);
++nready;
printf("%d end produce product ...\n", num);
pthread_cond_signal(&g_cond);
printf("%d signal\n", num);
pthread_mutex_unlock(&g_mutex);
sleep(5);
}
return NULL;
}
int main(void)
{
pthread_mutex_init(&g_mutex, NULL);
pthread_cond_init(&g_cond, NULL);
int i;
for (i=0; i<CONSUMERS_COUNT; i++)
{
pthread_create(&g_thread[i], NULL, consume, (void*)i);
}
sleep(1);
for (i=0; i<PRODUCERS_COUNT; i++)
{
pthread_create(&g_thread[CONSUMERS_COUNT + i], NULL, produce, (void*)i);
}
for (i=0; i<CONSUMERS_COUNT + PRODUCERS_COUNT; i++)
{
pthread_join(g_thread[i], NULL);
}
pthread_mutex_destroy(&g_mutex);
pthread_cond_destroy(&g_cond);
return 0;
}
pthread_cond_wait(cond, mutex)详解
- 对mutex进行解锁
- 等待条件,直到有线程向它发起通知
- 重新对mutex进行加锁操作
pthread_cond_signal(cond)详解
- 向第一个等待条件的线程发起通知,如果没有任何一个线程处理等待条件的状态,这个通知将被忽略