代码实现
如题,使用semaphore信号量和mutex互斥量实现多个生产者和消费者模型。本来是想只用信号量实现生产者消费者模型的,但是发现 只能在一个生产者和一个消费者之间,要在多个生产者和消费者模型必须和mutex互斥锁搭配使用才行,sem信号量只是控制并发数的。采用数组模拟产品区,代码中有一定的注释。需要Linux下线程相关知识进行支撑,这里不细说,直接看实现代码。
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <fcntl.h> #include <error.h> #include <sys/errno.h> #include <pthread.h> #include <semaphore.h> #define NUM 10 //产品区容量 int queue[NUM] = {0};//数组模拟产品区,生产者消费者运行模拟环形队列进行生产和消费 sem_t producer,customer;//信号量 int pro_i = 0;//生产者线程 访问下标 int cus_i = 0;//消费者线程 访问下标 pthread_mutex_t pro_lock = PTHREAD_MUTEX_INITIALIZER; pthread_mutex_t cus_lock = PTHREAD_MUTEX_INITIALIZER; //生产者 void* produce(void* arg) { int tmp; //生产从下标 0 -> N while(1) { sem_wait(&producer); //producer-- ,直到为0 产品区被填满 进行阻塞 //并行的生产者线程生成产品 pthread_mutex_lock(&pro_lock); tmp = queue[pro_i] = rand()%1000 ; pro_i = (pro_i+1)%NUM; pthread_mutex_unlock(&pro_lock); printf("%dth ###producer###:%d\n",(int)arg,tmp); sem_post(&customer);//customer++ sleep(rand()%2); } return NULL; } //消费者 void* custome(void* arg) { int tmp; //消费从下标0 -> N while(1) { sem_wait(&customer); // customer-- ,直到为0 产品区为空 进行阻塞 //并行的消费者线程访问消费产品 pthread_mutex_lock(&cus_lock); tmp = queue[cus_i]; queue[cus_i] = 0 ; cus_i = (cus_i+1)%NUM; pthread_mutex_unlock(&cus_lock); printf("%dth ***customer***:%d\n",(int)arg,tmp); sem_post(&producer);//producer++ sleep(rand()%2); } return NULL; } //使用信号量 实现生产者消费者模型 int main(int argc,char* argv[]) { srand((unsigned int)time(NULL)); //设置线程分离 pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED); pthread_t pro[3],cus[5]; int i; //初始化信号量 起初产品区为空 sem_init(&producer,0,NUM);//生产者 起初信号量为 NUM 产品区为空生产产品,当信号量为0 也就是产品满 阻塞等待消费者消费产品 sem_init(&customer,0,0); //消费者 起初信号量为 0 阻塞等待生产者生产产品 for( i= 0; i< 3;i++ ) { pthread_create(&pro[i],&attr,produce,(void*)i); } for( i= 0; i< 5;i++ ) { pthread_create(&cus[i],&attr,custome,(void*)i); } //销毁 信号量 sem_destroy(&producer); sem_destroy(&customer); //销毁 锁 pthread_mutex_destroy(&pro_lock); pthread_mutex_destroy(&cus_lock); //主线程退出 pthread_exit(NULL); return 0; }