您的位置:首页 > 运维架构 > Linux

Linux信号量机制(生产者消费者)

2015-10-16 11:13 746 查看
<span style="font-family: Arial; font-size: 14.399999618530273px; line-height: 26px;">该程序为Linux信号量机制实现程序,主要模拟了一般的生产者-消费者问题。(生产者-消费者问题是一个经典的进程同步问题,该问题最早由Dijkstra提出,用以演示他提出的信号量机制。在同一个进程地址空间内执行的两个线程。生产者线程生产物品,然后将物品放置在一个空缓冲区中供消费者线程消费。消费者线程从缓冲区中获得物品,然后释放缓冲区。当生产者线程生产物品时,如果没有空缓冲区可用,那么生产者线程必须等待消费者线程释放出一个空缓冲区。当消费者线程消费物品时,如果没有满的缓冲区,那么消费者线程将被阻塞,直到新的物品被生产出来。</span>
#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <pthread.h>#include <semaphore.h>#include <signal.h>#define N 5   // 消费者或者生产者的数目#define M 10 // 缓冲数目//int M=10;int in = 0; // 生产者放置产品的位置int out = 0; // 消费者取产品的位置int buff[M] = { 0 }; // 缓冲初始化为0,开始时没有产品sem_t empty_sem; // 同步信号量,当满了时阻止生产者放产品sem_t full_sem; // 同步信号量,当没产品时阻止消费者消费pthread_mutex_t mutex; // 互斥信号量,一次只有一个线程访问缓冲int product_id = 0; //生产者idint prochase_id = 0; //消费者id//信号处理函数void Handlesignal(int signo){printf("程序退出\n",signo);exit(0);}/* 打印缓冲情况 */void print() {int i;printf("产品队列为");for(i = 0; i < M; i++)printf("%d", buff[i]);printf("\n");}/* 生产者方法 */void *product() {int id = ++product_id;while(1) {//重复进行//用sleep的数量可以调节生产和消费的速度,便于观察sleep(2);sem_wait(&empty_sem);pthread_mutex_lock(&mutex);in= in % M;printf("生产者%d在产品队列中放入第%d个产品\t",id, in);buff[in]= 1;print();++in;pthread_mutex_unlock(&mutex);sem_post(&full_sem);}}/* 消费者方法 */void *prochase() {int id = ++prochase_id;while(1) {//重复进行//用sleep的数量可以调节生产和消费的速度,便于观察sleep(5);sem_wait(&full_sem);pthread_mutex_lock(&mutex);out= out % M;printf("消费者%d从产品队列中取出第%d个产品\t",id, out);buff[out]= 0;print();++out;pthread_mutex_unlock(&mutex);sem_post(&empty_sem);}}int main() {printf("生产者和消费者数目都为5,产品缓冲为10,生产者每2秒生产一个产品,消费者每5秒消费一个产品,Ctrl+退出程序\n");pthread_t id1;pthread_t id2;inti;int ret;//结束程序if(signal(SIGINT,Handlesignal)==SIG_ERR){//按ctrl+C产生SIGINT信号printf("信号安装出错\n");}// 初始化同步信号量int ini1 = sem_init(&empty_sem, 0, M);//产品队列缓冲同步int ini2 = sem_init(&full_sem, 0, 0);//线程运行同步if(ini1 && ini2 != 0) {printf("信号量初始化失败!\n");exit(1);}//初始化互斥信号量int ini3 = pthread_mutex_init(&mutex, NULL);if(ini3 != 0) {printf("线程同步初始化失败!\n");exit(1);}// 创建N个生产者线程for(i = 0; i < N; i++) {ret[i]= pthread_create(&id1[i], NULL, product, (void *) (&i));if(ret[i] != 0) {printf("生产者%d线程创建失败!\n", i);exit(1);}}//创建N个消费者线程for(i = 0; i < N; i++) {ret[i]= pthread_create(&id2[i], NULL, prochase, NULL);if(ret[i] != 0) {printf("消费者%d线程创建失败!\n", i);exit(1);}}//等待线程销毁for(i = 0; i < N; i++) {pthread_join(id1[i], NULL);pthread_join(id2[i],NULL);}exit(0);}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: