条件变量:可以引起阻塞,并非锁,要和互斥量组合使用
超时等待
int pthread_cond_timedwait(pthread_cond_t *restrict cond,pthread_mutex_t *restrict mutex,const struct timespec *restrict abstime);
struct timesec{
time_t tv_sec; //秒,绝对时间,填写的时候time(NULL)+600设置超时600s
long tv_nsec; //纳秒
}
条件变量阻塞等待
int pthread_cond_wait(pthread_cond_t *restrict cond,pthread_mutex_t *restrict mutex);
先释放mutex
阻塞在cond条件变量上
销毁一个条件变量
int pthread_cond_destroy(pthread_cond_t *cond);
初始化一个条件变量
int pthread_cond_init(pthread_cond_t *restrict cond,const pthread_condattr_t *restrict attr);
pthread_cond_t cond=PTHREAD_COND_INITIALIZER;
至少唤醒一个阻塞在条件变量cond上的线程
int pthread_cond_signal(pthread_cond_t *cond);
唤醒阻塞在条件变量cond上的全部线程
int pthread_cond_broadcast(pthread_cond_t *cond);
条件变量:避免没有必要的竞争
cond_product.c
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <stdlib.h>
pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond=PTHREAD_COND_INITIALIZER;
int beginnum=100;
typedef struct _ProdInfo{
int num;
struct _ProdInfo *next;
}ProdInfo;
ProdInfo *Head=NULL;
void* thr_producter(void *arg)
{
//负责在链表中添加数据
while(1){
ProdInfo *prod=malloc(sizeof(ProdInfo));
prod->num=beginnum++;
printf("----%s----self=%lu----%d\n",__FUNCTION__,pthread_self(),prod->num);
pthread_mutex_lock(&mutex);
//加入链表
prod->next=Head;
Head=prod;
pthread_mutex_unlock(&mutex);
//发起通知
pthread_cond_signal(&cond);
sleep(rand()%4);
}
return NULL;
}
void* thr_customer(void *arg)
{
ProdInfo *prod=NULL;
while(1){
//取链表的数据
pthread_mutex_lock(&mutex);
while(Head==NULL){
pthread_cond_wait(&cond,&mutex); // 在此之前必须加锁
}
prod=Head;
Head=Head->next;
printf("----%s----self=%lu----%d\n",__FUNCTION__,pthread_self(),prod->num);
pthread_mutex_unlock(&mutex);
sleep(rand()%2);
free(prod);
}
return NULL;
}
int main()
{
pthread_t tid[2];
pthread_create(&tid[0],NULL,thr_producter,NULL);
pthread_create(&tid[1],NULL,thr_customer,NULL);
pthread_create(&tid[2],NULL,thr_customer,NULL);
pthread_join(tid[0],NULL);
pthread_join(tid[1],NULL);
pthread_join(tid[2],NULL);
pthread_mutex_destroy(&mutex);
pthread_cond_destroy(&cond);
return 0;
}