问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

在linux下用c语言实现用多进程同步方法演示“生产者-消费者”问题

发布网友 发布时间:2022-04-30 16:24

我来回答

2个回答

热心网友 时间:2023-10-08 23:36

这个问题需要的知识主要包括:

1 多进程间进行通信;

2 使用同步信号量(semaphore)和互斥信号量(mutex)进行数据保护。

参考代码如下,可以参照注释辅助理解:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <semaphore.h>
#define N 2   // 消费者或者生产者的数目
#define 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 proct_id = 0;   //生产者id
int prochase_id = 0; //消费者id
/* 打印缓冲情况 */
void print()
{
int i;
for(i = 0; i < M; i++)
   printf("%d ", buff[i]);
printf("\n");
}
/* 生产者方法 */ 
void *proct()
{
int id = ++proct_id;

while(1)
{
   // 用sleep的数量可以调节生产和消费的速度,便于观察
   sleep(1);
   //sleep(1);
  
   sem_wait(&empty_sem);
   pthread_mutex_lock(&mutex);
  
   in = in % M;
   printf("proct%d in %d. like: \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(1);
//sleep(1);
  
   sem_wait(&full_sem);
   pthread_mutex_lock(&mutex);
  
   out = out % M;
   printf("prochase%d in %d. like: \t", id, out);
  
   buff[out] = 0;
   print();
   ++out;
  
   pthread_mutex_unlock(&mutex);
   sem_post(&empty_sem);
}
}
int main()
{
pthread_t id1[N];
pthread_t id2[N];
int i;
int ret[N];

// 初始化同步信号量
int ini1 = sem_init(&empty_sem, 0, M); 
int ini2 = sem_init(&full_sem, 0, 0);  
if(ini1 && ini2 != 0)
{
   printf("sem init failed \n");
   exit(1);

//初始化互斥信号量 
int ini3 = pthread_mutex_init(&mutex, NULL);
if(ini3 != 0)
{
   printf("mutex init failed \n");
   exit(1);

// 创建N个生产者线程
for(i = 0; i < N; i++)
{
   ret[i] = pthread_create(&id1[i], NULL, proct, (void *)(&i));
   if(ret[i] != 0)
   {
    printf("proct%d creation failed \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("prochase%d creation failed \n", i);
    exit(1);
   }
}
//销毁线程
for(i = 0; i < N; i++)
{
   pthread_join(id1[i],NULL);
   pthread_join(id2[i],NULL);
}
exit(0); 
}

在Linux下编译的时候,要在编译命令中加入选项-lpthread以包含多线程支持。比如存储的C文件为demo.c,要生成的可执行文件为demo。可以使用命令:

gcc demo.c -o demo -lpthread

程序中为便于观察,使用了sleep(1);来暂停运行,所以查看输出的时候可以看到,输出是每秒打印一次的。

热心网友 时间:2023-10-08 23:37

自己稍微改改

#include <stdio.h>
#include <pthread.h>
char data[5];//仓库,用于存放char
int size = 0;//库存数
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t full = PTHREAD_COND_INITIALIZER;
pthread_cond_t empty = PTHREAD_COND_INITIALIZER;
void print(){
  int i;
  for(i=0;i<size;i++){
    printf("%c ",data[i]);
  }
  printf("\n");
}
//生产者线程
void* proct(void *p){
  char c;
  for(c='A';c<='Z';c++){
    pthread_mutex_lock(&mutex);//mutex内部才能使用cond
    while(size==5) //阻塞生产同时释放互斥 (旋锁)
      pthread_cond_wait(&full,&mutex);//阻塞生产线程
    printf("PUSH %c\n",c);
    data[size] = c;
    usleep(10000);
    size++;
    print();
    pthread_cond_broadcast(&empty);//释放消费cond
    pthread_mutex_unlock(&mutex);
    usleep(200000);
  }
}
//消费者线程
void* custom(void *p){
  int i;
  for(i=0;i<52;i++){
    pthread_mutex_lock(&mutex);
    while(size==0)
      pthread_cond_wait(&empty,&mutex);
    printf("POP %c\n",data[size-1]);
    size--;
    print();
    pthread_cond_broadcast(&full);
    pthread_mutex_unlock(&mutex);
    usleep(400000);
  }
}
int main(){
  pthread_t id1,id2,id3;
  pthread_create(&id1,0,proct,0);
  pthread_create(&id3,0,proct,0);
  pthread_create(&id2,0,custom,0);
  pthread_join(id1,0); pthread_join(id2,0);
  pthread_join(id3,0);
  pthread_mutex_destroy(&mutex);
}

声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
手机导航地图语音怎么下载 如何分别真金和仿金首饰 怎样区分真金和仿金首饰呢 小学生新年晚会主持人的串词!!(不要太多)急 大大后天就需要了!!!_百度... 周年晚会策划公司 奥格瑞玛传送门大厅在哪 奥格瑞玛传送门大厅怎么走 锻炼颈椎的几个动作 水多久能结冰 冰能在多长时间内形成 请问水低于0度会结冰吗? 如何防止脱发严重 同一个网线是不是换台主机ip就会变啊我的变了还上不去网了怎么回事,我该怎么办 我把别人的主机装在自己家的电脑上,电脑的ip地址会更换吗? 硬盘换在其他电脑主机,ip和mac地址会改变吗? C语言多进程改变变量问题 我如果把我的电脑主机换了,那我的电脑IP会改变吗? linux简单的C语言程序,多进程,为什么存在死循环的时候不打印字符?死循环明明在打印语句的后面呀? 怎么在win7环境下用C语言写多进程 c语言多进程编程 什么软件可以让没有手机卡的手机给别人打电话?我有无线,没有手机卡。那个人有卡没有网。 没有手机卡,怎么才能打电话 我现在只有网路却没有sim卡,急需联系一个人,对方无网络。有没有有什么软件可以用网给对方打电话 平安普惠贷款还款日到了,可是我身份证和银行卡都丢了,扣款账号不能用了怎么办? 平安普惠贷款可以更换还款账号吗?谢谢 平安普惠怎么解除绑定的银行卡 平安普惠怎么更换银行卡 我在平安普惠贷款时绑定的还款银行卡掉了怎么办? 平安普惠换卡还扣钱 我在平安惠普的贷款到期因老银行卡坏了现在怎么还上 平安普惠可以更换还款人吗? 我的手机小米三开了儿童模式,但是忘记密码了,怎么办?&#xF64F;&#xF64F; 请问怎么在win7环境下用C语言写多进程?(可以的话,请附上简单代码,谢谢!) 每台主机的IP号是不是永远不变的? C语言同时执行不同过程可以吗? 在控制台程序下,如何实现c或者c++的多进程 C/C++ 如何监控多个进程,实现崩溃自动重启? 当一台主机从一个网络移到另一个网络时,IP地址和MAC地址可改变吗? 用多进程解决生产者消费者问题,用C或C++语言实现 cpu换了电脑ip地址会不会变 多进程并发售票 用c语言写 在linux下c语言编程有关进程的问题 香港影片,女主角家有钱,被人在桌子上*,坏人被一*爆头,男主角演过仙鹤神针电视剧 什么是多线程、多进程? 13. 在多进程的并发系统中,肯定不会因竞争( )而产生死锁. A.打印机 B.磁带机 C.磁盘 D.CPU 为什么双频的路由器2.4g 的信号没了,只有5g 的信号了?怎么解决 企业所得税A类报表里的营业成本包括管理费用财务费用这些吗要怎么填 为什么我家极路由3pro只能上5G网? 请问老师,在申报企业所得税的时候,发生的管理费用,财务费用应该填写在哪里呢? 路由器只开5g好处 所得税申报表里的财务费用一栏应该怎么填啊? 小米路由器怎么只有5g信号??