利用条件变量实现多线程生产者消费者问题
2013-04-08 09:48
501 查看
以下程序实现linux多线程下一个生产者多个消费者的问题。
本文出自 “退而结网” 博客,请务必保留此出处http://zhouxiaodan.blog.51cto.com/1177793/1173308
/* 使用条件变量时,线程在不满足条件时会被挂起。 在消费品都消费完毕,生产者线程停止生产后, 消费者线程因为缓冲区内容为空,将一直挂起。 需设置一个全局变量start,当生产者已经停止时,需告知其他消费者解除挂起的状态。 */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <pthread.h> #define NUMS 10000 //表示生产,消费的次数 #define CAPACITY 50 //定义缓冲区最大值 int capacity = 0; //当前缓冲区的产品个数 pthread_mutex_t mylock = PTHREAD_MUTEX_INITIALIZER;//互斥量 pthread_cond_t mycond = PTHREAD_COND_INITIALIZER;//条件变量 int start = 0; void *produce(void *args) { int i = 0; for (; i < NUMS; ) { pthread_mutex_lock(&mylock);//加锁 if (capacity >= CAPACITY) //当前产品个数大于等于缓冲区最大值,则不把产品放入缓冲区。 { printf("缓冲区已满,无法放入产品\n"); pthread_cond_wait(&mycond, &mylock); } else {//将产品放入缓冲区 ++capacity; printf("生产者存入一个产品, 缓冲区大小为:%d\n", capacity); i++; } pthread_mutex_unlock(&mylock); pthread_cond_broadcast(&mycond); } pthread_mutex_lock(&mylock);//加锁 printf("生产者finish!!!!\n"); start = 1; pthread_mutex_unlock(&mylock); pthread_cond_broadcast(&mycond); return ((void *) 0); } void * consume(void *args) { int i = 0; char *p = (char*)args; printf("消费者%s start!!!!!!!!!\n", p); for (; i < NUMS; ) { pthread_mutex_lock(&mylock); if (capacity > 0) { --capacity; printf("消费者%s消耗一个产品,缓冲区大小为:%d\n", p, capacity); i++; } else if(capacity <= 0 && start != 1) { //当没获取到资源时,将被wait挂起。当其他线程退出后,将不会有broadcast对wait进行解除。 //这将导致循环未结束的线程挂起。所以需引入下一个分支的判断 printf("%s 缓冲区已空,无法消耗产品\n", p); pthread_cond_wait(&mycond, &mylock); } else if(capacity <= 0 && start == 1) {//start为1,说明生产者进程已经停止,所以应该释放锁,同时,跳出循环,结束线程。 pthread_mutex_unlock(&mylock); //pthread_cond_broadcast(&mycond);//可以不加??? break; } pthread_mutex_unlock(&mylock); pthread_cond_broadcast(&mycond); } pthread_mutex_lock(&mylock); printf("消费者%s finish!!!!!!!!!\n", p); pthread_cond_broadcast(&mycond); pthread_mutex_unlock(&mylock); return ((void *) 0); } #define CNUM 5 int main(int argc, char** argv) { int err; pthread_t produce_tid; pthread_t consume_tid[CNUM]; void *ret; err = pthread_create(&produce_tid, NULL, produce, NULL);//创建线程 if (err != 0) { printf("线程producer创建失败:%s\n", strerror(err)); exit(-1); } int i = 0; char *pfree[CNUM] = {0}; for(i= 0; i < CNUM; i++) { char* pc = NULL; pc = (char*)malloc(sizeof(char) * (strlen("consumer") + 2)); sprintf(pc, "consumer%d", i); pfree[i] = pc; err = pthread_create(consume_tid + i, NULL, consume, (void*)pc); if (err != 0) { printf("线程consumer创建失败:%s\n", strerror(err)); continue; //exit(-1); } } err = pthread_join(produce_tid, &ret);//主线程等到子线程退出 if (err != 0) { printf("生产着线程分解失败:%s\n", strerror(err)); exit(-1); } for(i= 0; i < CNUM; i++) { free(pfree[i]); err = pthread_join(consume_tid[i], NULL); if (err != 0) { printf("消费者线程分解失败:%s\n", strerror(err)); continue; } } return (EXIT_SUCCESS); }
本文出自 “退而结网” 博客,请务必保留此出处http://zhouxiaodan.blog.51cto.com/1177793/1173308
相关文章推荐
- 关于网宿厦门研发中心笔试的一道PV操作题:利用java中的多线程实现生产者与消费者的同步问题
- java利用lock和unlock实现消费者与生产者问题(多线程)
- Linux下用条件变量实现多线程间生产者与消费者问题
- 多线程用互斥锁和条件变量实现生产者和消费者-------循环任务队列
- java多线程总结六:经典生产者消费者问题实现
- JAVA多线程实现生产者消费者问题
- java多线程实现生产者与消费者---经典问题
- 20180126:通过Callable实现多线程、生产者-消费者问题、多线程下载(复制)文件
- 多线程(线程间通信-多生产者多消费者问题-JDK1.5解决办法-范例),停止线程,线程中方法的区别,匿名内部类实现多线程,线程总结
- 利用PPL实现复杂的多线程模式的生产者-消费者
- 多线程下生产者消费者问题的五种同步方法实现
- java 多线程 22 :生产者/消费者模式 进阶 利用await()/signal()实现
- 关于多线程的经典问题——生产者消费者,不能实现循环工作。
- 多线程--C#利用多线程实现消费者和生产者模式
- C++ 11新特性之用多线程实现生产者消费者问题
- linux下多线程互斥量实现生产者--消费者问题和哲学家就餐问题
- 多线程实现生产者消费者问题 详细注释 事件+临界区 信号量+临界区2种方法
- Linux下利用信号量函数和共享内存函数和C语言实现生产者消费者问题
- Java多线程15:Queue、BlockingQueue以及利用BlockingQueue实现生产者/消费者模型
- Java多线程系列-Queue、BlockingQueue以及利用BlockingQueue实现生产者/消费者模型