线程 – 条件变量
使用到的函数声明
#include <pthread.h>
// 条件变量不是锁 要和互斥量组合使用
// 超时等待
int pthread_cond_timedwait(pthread_cond_t *restrict cond,
pthread_mutex_t *restrict mutex,
const struct timespec *restrict abstime);
struct timespec {
__kernel_time_t tv_sec; /* seconds */ // 当前时间到1970年1月1日0:0:0的秒数
long tv_nsec; /* nanoseconds */ // 纳秒数
};
// tv_sec 绝对时间,填写时 time(NULL) + 600 ==> 设置超时600秒
// 1s = 1000ms(毫秒)
// 1ms = 1000us(微秒)
// 1us = 1000ns(纳秒)
// 条件变量阻塞等待
int pthread_cond_wait(pthread_cond_t *restrict cond,
pthread_mutex_t *restrict mutex);
// 销毁
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_broadcast(pthread_cond_t *cond);
// 唤醒至少一个阻塞在条件变量cond上的多线程
int pthread_cond_signal(pthread_cond_t *cond);
条件变量的作用:避免没有必要的竞争 。
生产者消费者问题
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<fcntl.h>
#include<string.h>
#include<pthread.h>
// 定义开始编号
int beginnum = 1;
// 链表结构体
typedef struct _ProdInfo{
int num;
struct _ProdInfo *next;
}ProdInfo;
// 定义互斥量
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
// 定义信号量
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
// 定义头节点
ProdInfo *Head = NULL;
// 生产者
void *thr_producter(void *arg)
{
// 负责链表上添加数据
while(1){
ProdInfo * prod = malloc(sizeof(ProdInfo));
prod->num = beginnum++;
printf("生产者---%s---%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()%2);
}
return NULL;
}
// 消费者
void* thr_customer(void *arg)
{
ProdInfo *prod = NULL;
while(1){
// 取链表数据
pthread_mutex_lock(&mutex);
// 没有数据
//if(Head == NULL){
while(Head == NULL){
pthread_cond_wait(&cond,&mutex); // 再次之前先加锁
}
prod = Head;
Head = Head->next;
printf("消费者---%s---%lu---产品编号:%d \n",__FUNCTION__, pthread_self(), prod->num);
pthread_mutex_unlock(&mutex);
sleep(rand()%4);
free(prod);
}
return NULL;
}
int main()
{
int n = 5,i=0;
pthread_t tid[n];
for(i; i<2; i++){
pthread_create(&tid[i],NULL,thr_producter,NULL);
}
for(i; i<n; i++){
pthread_create(&tid[i],NULL,thr_customer,NULL);
}
for(i=0; i<n; i++){
pthread_join(tid[i],NULL);
}
pthread_mutex_destroy(&mutex);
pthread_cond_destroy(&cond);
return 0;
}
运行结果 :
[dai@localhost 06线程-2]$ ./05条件变量
生产者—thr_producter—140630486611712—产品编号:1
生产者—thr_producter—140630478219008—产品编号:2
生产者—thr_producter—140630478219008—产品编号:3
消费者—thr_customer—140630469826304—产品编号:3
消费者—thr_customer—140630453040896—产品编号:2
消费者—thr_customer—140630461433600—产品编号:1
生产者—thr_producter—140630486611712—产品编号:4
生产者—thr_producter—140630486611712—产品编号:5
生产者—thr_producter—140630486611712—产品编号:6
生产者—thr_producter—140630478219008—产品编号:7
消费者—thr_customer—140630453040896—产品编号:7
生产者—thr_producter—140630486611712—产品编号:8
生产者—thr_producter—140630478219008—产品编号:9
生产者—thr_producter—140630478219008—产品编号:10
消费者—thr_customer—140630469826304—产品编号:10
消费者—thr_customer—140630461433600—产品编号:9
^C