生产者与消费者问题

  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3. #include <unistd.h>  
  4. #include <pthread.h>  
  5. #include <semaphore.h>  
  6.   
  7. #define BUFFSIZE 9 // 缓冲池大小   
  8.   
  9. struct queue_type     //缓冲池队列   
  10. {  
  11.     int buff[BUFFSIZE];  
  12.     int front;  //队头,消费者从对头取出"产品”   
  13.     int rear;   //队尾,生产者从队尾放入"产品“   
  14. }Q={{0},0,0};         
  15.   
  16. sem_t empty; // 生产者私有信号量,表示空缓冲区数目 。   
  17. sem_t full;   //消费者私有变量,表示有产品的缓冲区数目。   
  18. pthread_mutex_t mutex; // 公有信号量,用于实现对临界区互斥访问   
  19.   
  20. int producer_id = 0;   //生产者编号,初值为0   
  21. int consumer_id = 0;   //消费者编号,初值为0   
  22.   
  23. /* 打印缓冲池情况*/  
  24. void print()  
  25. {  
  26.      int i;  
  27.      for(i = 0; i < BUFFSIZE; i++)  
  28.      printf("%d ", Q.buff[i]);  
  29.      printf("\n");  
  30. }  
  31.   
  32. /*生产者*/  
  33. void *producer()  
  34. {  
  35.      int id=++producer_id;  
  36.   
  37.      while(1)  
  38.       {  
  39.              sleep(1);  //        
  40.     
  41.              sem_wait(&empty);  //申请空缓冲区   
  42.              pthread_mutex_lock(&mutex);    //申请队列互斥   
  43.   
  44.              Q.buff[Q.rear] = 1;   //将产品放入rear所指向的缓冲区   
  45.              printf("producer number<%d> thread idetifier:%u put into buffer[%d].The buffer is like: \t", id, ((unsigned int)pthread_self()),Q.rear+1);  
  46.              print();    
  47.              Q.rear = (Q.rear+1) % BUFFSIZE;  
  48.     
  49.              pthread_mutex_unlock(&mutex);  //释放队列互斥   
  50.              sem_post(&full);   //释放满缓冲区   
  51.       }  
  52. }  
  53.   
  54. /* 消费者*/  
  55. void *consumer()  
  56. {  
  57.      int id=++consumer_id;  
  58.      while(1)  
  59.       {  
  60.              sleep(1);  
  61.   
  62.              sem_wait(&full);  //申请满缓冲区   
  63.              pthread_mutex_lock(&mutex);     //申请队列互斥   
  64.      
  65.              Q.buff[Q.front] = 0;            //从front所指向的缓冲区取产品   
  66.              printf("consumer number<%d> thread idetifier:%u get from buffer[%d].The buffer is like: \t", id,((unsigned int)pthread_self()), Q.front+1);  
  67.              print();  
  68.              Q.front = (Q.front+1) % BUFFSIZE;  
  69.     
  70.              pthread_mutex_unlock(&mutex);    //释放队列互斥   
  71.              sem_post(&empty);                //释放空缓冲区   
  72.       }  
  73. }  
  74.   
  75. int main()  
  76. {  
  77.     int M,N;  //M为生产者者数目,N为消费者数目   
  78.     printf("please input the producers number: ");  
  79.     scanf("%d",&M);  
  80.     printf("please input the consumers number: ");  
  81.     scanf("%d",&N);  
  82.     pthread_t id1[M];       //存储生产者线程ID   
  83.     pthread_t id2[N];       //存储消费者者线程ID   
  84.     int i;  
  85.     int ret1[M],ret2[N];  //存储创建生产者和消费者线程的返回值。   
  86.   
  87.   
  88. /*初始化empty和full私有信号量 */  
  89.     int ini1 = sem_init(&empty, 0, BUFFSIZE);//初始化empty信号量,大小为Buffersize ,初始化成功返回零,失败返回-1    
  90.     int ini2 = sem_init(&full, 0, 0);        //初始化full信号量,大小为0                                   
  91.     if((ini1 || ini2)!=0)   //  
  92.     {  
  93.              printf("sem init failed \n");  
  94.              exit(1);  
  95.     }  
  96.   
  97. /*初始化公有信号量 mutex*/  
  98.     int ini3 = pthread_mutex_init(&mutex, NULL);    //以默认方式创建互斥锁(快速互斥锁) ,初始化为未锁状态,成功返回0   
  99.     if(ini3 != 0)  
  100.     {  
  101.             printf("mutex init failed \n");  
  102.             exit(1);  
  103.     }  
  104.       
  105. /*创建生产者线程*/  
  106.     for(i = 0; i < M; i++)  
  107.     {  
  108.             ret1[i] = pthread_create(&id1[i], NULL, producer, (void *)(&i));    //循环创建生产者线程,成功返回0   
  109.             if(ret1[i] != 0)  
  110.             {  
  111.                printf("producer%d creation failed \n", i);  
  112.                exit(1);  
  113.             }  
  114.     }  
  115.       
  116. /*创建消费者线程*/   
  117.     for(i = 0; i < N; i++)  
  118.     {  
  119.             ret2[i] = pthread_create(&id2[i], NULL, consumer, NULL);         //循环创建消费者线程,成功返回0   
  120.             if(ret2[i] != 0)  
  121.             {  
  122.                printf("consumer%d creation failed \n", i);  
  123.                exit(1);  
  124.             }  
  125.     }  
  126.       
  127. /*销毁线程*/  
  128.     for(i = 0; i < M; i++)  
  129.     {  
  130.             pthread_join(id1[i],NULL);   //对创建的生产者线程进行资源回收   
  131.     }  
  132.     for(i = 0; i < N; i++)  
  133.     {   
  134.             pthread_join(id2[i],NULL);   //对创建的消费者线程进行资源回收   
  135.     }  
  136.   
  137.     exit(0);  
  138. }  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
生产者消费者问题可以使用线程和信号量来实现。 以下是一个简单的C语言程序,使用互斥锁和条件变量来解决生产者消费者问题: ```c #include <stdio.h> #include <stdlib.h> #include <pthread.h> #include <semaphore.h> #define BUFFER_SIZE 10 int buffer[BUFFER_SIZE]; int in = 0; int out = 0; pthread_mutex_t mutex; sem_t empty; sem_t full; void* producer(void* arg) { int item; while (1) { item = rand(); sem_wait(&empty); pthread_mutex_lock(&mutex); buffer[in] = item; in = (in + 1) % BUFFER_SIZE; printf("Produced item: %d\n", item); pthread_mutex_unlock(&mutex); sem_post(&full); } } void* consumer(void* arg) { int item; while (1) { sem_wait(&full); pthread_mutex_lock(&mutex); item = buffer[out]; out = (out + 1) % BUFFER_SIZE; printf("Consumed item: %d\n", item); pthread_mutex_unlock(&mutex); sem_post(&empty); } } int main() { pthread_t tid1, tid2; pthread_mutex_init(&mutex, NULL); sem_init(&empty, 0, BUFFER_SIZE); sem_init(&full, 0, 0); pthread_create(&tid1, NULL, producer, NULL); pthread_create(&tid2, NULL, consumer, NULL); pthread_join(tid1, NULL); pthread_join(tid2, NULL); pthread_mutex_destroy(&mutex); sem_destroy(&empty); sem_destroy(&full); return 0; } ``` 在该程序中,生产者线程消费者线程无限循环地执行。生产者线程生成一个随机数并将其放入缓冲区中,然后唤醒消费者线程消费者线程从缓冲区中获取一个项目并打印出来,然后唤醒生产者线程互斥锁用于保护缓冲区的读写操作,而信号量则用于控制缓冲区的空闲和已用空间。当缓冲区已满时,生产者线程被阻塞在 sem_wait(&empty) 处,直到有空间可用。当缓冲区为空时,消费者线程被阻塞在 sem_wait(&full) 处,直到有项目可用。 注意,该程序仅为示例,实际应用中可能需要更复杂的同步机制和错误处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值