Linux系统编程|Linux线程间通信之条件变量(十七)


Linux线程间通信之条件变量(十七)

  • 1.条件变量
  • 2.条件变量初始化函数
  • 3.释放条件变量函数
  • 4.等待条件函数
  • 5.限时等待条件函数
  • 6.唤醒等待在条件变量上的线程
  • 7.参考代码

1.条件变量 与互斥锁不同,条件变量是用来等待而不是用来上锁的,条件变量本身不是锁! 条件变量用来自动阻塞一个线程,直到某特殊情况发生为止。通常条件变量和互斥锁同时使用。 条件变量的两个动作:
(1)条件不满, 阻塞线程 。
(2)当条件满足, 通知阻塞的线程开始工作 条件变量的类型: pthreadcondt。
2.条件变量初始化函数
int pthread_cond_init(pthread_cond_t *restrict cond,const pthread_condattr_t *restrict attr);

功能:
初始化一个条件变量。
参数:
cond:指向要初始化的条件变量指针。
attr:条件变量属性,通常为默认值,传NULL即可也可以使用静态初始化的方法,初始化条件变量:
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

返回值:
成功:0.
失败: 非0 ,错误号。
3.释放条件变量函数
int pthread_cond_destroy(pthread_cond_t *cond);

功能:
销毁一个条件变量
参数:
cond:指向要初始化的条件变量指针。
返回值:
成功:0.
失败: 非0 ,错误号。
4.等待条件函数
int pthread_cond_wait(pthread_cond_t *restrict cond,pthread_mutex_t *restrict mutex);

功能:
阻塞等待一个条件变量。
a) 阻塞等待条件变量cond(参1)满足
b) 释放已掌握的互斥锁(解锁互斥量)相当于pthread_mutex_unlock(&mutex);
其中 a) b) 两步为一个原子操作。
c) 当被唤醒,pthread_cond_wait函数返回时,解除阻塞并重新申请获取互斥锁pthread_mutex_lock(&mutex);
参数:
cond:指向要初始化的条件变量指针。
mutex:互斥锁。
【Linux系统编程|Linux线程间通信之条件变量(十七)】返回值:
成功:0.
失败: 非0 ,错误号。
5.限时等待条件函数
int pthread_cond_timedwait(pthread_cond_t *restrict cond,pthread_mutex_t *restrict mutex,const struct *restrict abstime);

功能:
限时等待一个条件变量。
参数:
cond:指向要初始化的条件变量指针。
mutex:互斥锁。
abstime:绝对时间。
返回值:
成功:0.
失败: 非0 ,错误号。
6.唤醒等待在条件变量上的线程
int pthread_cond_signal(pthread_cond_t *cond);

功能:
唤醒至少一个阻塞在条件变量上的线程
参数:
cond:指向要初始化的条件变量指。
返回值:
成功:0.
失败: 非0 ,错误号。
说明:
int pthreadcondbroadcast(pthreadcondt *cond); 功能: 给阻塞在条件变量上的所有线程发送信号 参数: cond 条件变量的地址

7.参考代码
//============================================================================= // File Name: thread_cond.c // Author: FengQQ // // Description: 条件变量 // Annotation: 与互斥锁不同,条件变量是用来等待而不是用来上锁的, //条件变量本身不是锁!条件变量用来自动阻塞一个线程, //直到某特殊情况发生为止。通常条件变量和互斥锁同时使用。 //条件变量的两个动作:1)条件不满, 阻塞线程 。 //2)当条件满足, 通知阻塞的线程开始工作。 //条件变量的类型: pthreadcondt。 // //《条件变量实现生产者与消费者代码》 // // Created by FengQQ. 2020-10-05 //============================================================================= #include .h> #include #include .h> #include .h> #include #include /types.h> #include .h> #include #define BUFFER_SIZE5//生产库存大小 #define PRODUCT_CNT30//产品生产总数typedef struct product_cons_t { int buffer[BUFFER_SIZE]; //生产产品值 pthread_mutex_t lock; //互斥锁 volatile int int readpos,writepos; //读写位置 pthread_cond_t notempty; //条件变量,为空 pthread_cond_t notfull; //非满 }Product_Cons_T; Product_Cons_T product_cons; void init(Product_Cons_T *p) { pthread_mutex_init(&p->lock,NULL); //互斥锁 pthread_cond_init(&p->notempty,NULL); //条件变量 pthread_cond_init(&p->notfull,NULL); //条件变量 p->readpos = 0; //读写位置 p->writepos = 0; }void finish(Product_Cons_T *p) { pthread_mutex_destroy(&p->lock); //互斥锁 pthread_cond_destroy(&p->notempty); //条件变量 pthread_cond_destroy(&p->notfull); //条件变量 p->readpos = 0; //读写位置 p->writepos = 0; }//-------------生产一个数据-------------- void put(Product_Cons_T *p,int data)//输入产品子函数 { pthread_mutex_lock(&p->lock); if((p->writepos+1)%BUFFER_SIZE == p->readpos) { printf("product wait for not full\r\n"); pthread_cond_wait(&p->notfull,&p->lock); } p->buffer[p->writepos] = data; (p->writepos)++; if(p->writepos >= BUFFER_SIZE) p->writepos = 0; pthread_cond_signal(&p->notempty); pthread_mutex_unlock(&p->lock); } //-------------取出一个数据-------------- int get(Product_Cons_T *p)//输入产品子函数 { int data; pthread_mutex_lock(&p->lock); if(p->readpos == p->writepos) { printf("consumer wait for not empty\r\n"); pthread_cond_wait(&p->notempty,&p->lock); } data = https://www.it610.com/article/p->buffer[p->readpos]; (p->readpos)++; if(p->readpos >= BUFFER_SIZE) p->readpos = 0; pthread_cond_signal(&p->notfull); pthread_mutex_unlock(&p->lock); return data; } //-----------------生产者线程----------------- void *pthread_product(void *arg) { int n; for(n=1; n<=50; ++n) { sleep(1); printf("put the %d product...\r\n",n); put(&product_cons,n); printf("put the %d product success\r\n",n); } printf("product stopped\r\n"); return NULL; } //-----------------消费者线程----------------- void *pthread_consumer(void *arg) { static int cnt = 0; int num; while(1) { sleep(2); printf("get product...\r\n"); num = get(&product_cons); printf("get the %d product success\r\n",num); if(++cnt == PRODUCT_CNT) break; } printf("consumer stopped\r\n"); }int main(int argc,char *argv[]) { int ret; pthread_t ptid1,ptid2; init(&product_cons); //初始化相关操作 ret = pthread_create(&ptid1,NULL,pthread_product,NULL); //创建线程1 if(ret != 0) { printf("create new pthread product failed...\r\n"); return -1; } ret = pthread_create(&ptid2,NULL,pthread_consumer,NULL); //创建线程2 if(ret != 0) { printf("create new pthread consumer failed...\r\n"); return -1; } ret = pthread_join(ptid1,NULL); //回收线程1资源 if(ret != 0) { printf("pthread product join failed...\r\n"); } ret = pthread_join(ptid2,NULL); //回收线程2资源 if(ret != 0) { printf("pthread consumer join failed...\r\n"); } finish(&product_cons); //释放相关操作 return 0; }

Linux线程间通信之信号(十八)
链接: link.(https://blog.csdn.net/qq_39721016/article/details/120478269?spm=1001.2014.3001.5501)

    推荐阅读