2020-12-25

操作系统实验:生产者消费者问题

问题:
在系统中有 个缓冲区(每个可以放1个产品)构成的仓库。有 个生产者 ,每个生产者 可以生产 个产品。有 个消费者 ,每个消费者消费若干个产品,直到消费完所有的产品为止,即 ,其中 是消费者 实际消费的产品个数。
输入:生产者个数 、消费者个数 、缓冲区个数 、每个生产者生产产品的个数 等。
输出:生产者-消费者并发执行的过程、每个进程的状态变化。如:
(1)生产者 将第X个产品放入仓库;
(2)消费者 从仓库中消费第Y个产品;
(3)生产者 阻塞;
(4)消费者 阻塞;
(5)生产者 被唤醒;
(6)消费者 被唤醒。

pc.c:

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<semaphore.h>
#include<pthread.h>
  int PRODUCER; //生产者数量
 int  CONSUMER; //消费者数量
 int  BUFFER;//缓冲区数量
 int k[100];
 int flagp[100];
 int flagc[100];
 int kp[100];
 int kc[100];
sem_t empty,full;//同步信号量
pthread_mutex_t mutex;//互斥信号量
int buffer[100]; //缓冲区
int sum=0;
int producer_id=0,consumer_id=0;//生产者消费者ID
int index_in=0,index_out=0;//生产者 消费者 存放 消费的位置

void print()//输出缓冲区
{
   int i;
   printf("\n缓冲区:\n");
   for(i=0;i<BUFFER;i++)
   {
      printf("---");
   }
   printf("\n");
   for(i=0;i<BUFFER;i++)
      printf("|%d|",buffer[i]);
   printf("\n");
   for(i=0;i<BUFFER;i++)
   {
      printf("---");
   }
   printf("\n\n");
}
void *Producer()//生产者函数
{
   int ID=++producer_id;
   while(kp[ID]<k[ID])
   {
      if(empty.__align==0){
                printf("生产者%d阻塞 \n",ID);
             flagp[ID]=1;
        }
        sleep(3);
     sem_wait(&empty);
        pthread_mutex_lock(&mutex);
     index_in=index_in%BUFFER;
    if(flagp[ID]==1){
     printf("生产者%d唤醒 \n",ID);
     flagp[ID]=0;
     }
     buffer[index_in]=1;//缓冲区置1
        kp[ID]++;
        printf("生产者 %d 将第%d个产品放入仓库 \n",ID,kp[ID]);
     print();//输出缓冲区情况
     index_in++;
     pthread_mutex_unlock(&mutex);
     sem_post(&full);
   }
if(kp[ID]<k[ID])
exit(0);
}
void *Consumer()//消费者函数
{
   int ID=++consumer_id;
   flagc[ID]=0;
   while(sum)
   {
         if(full.__align==0){
                printf("消费者%d阻塞 \n",ID);
             flagc[ID]=1;
        }
     sleep(3);
     sem_wait(&full);
        pthread_mutex_lock(&mutex);
     index_out=index_out%BUFFER;
    if(flagc[ID]==1){
     printf("消费者%d唤醒 \n",ID);
     flagc[ID]=0;
     }
      buffer[index_out]=0;//缓冲区置0
        kc[ID]++;
        sum--;
        printf("\033[01;34m消费者 %d 在仓库中消费了第%d个产品\033[0m\n",ID,kc[ID]);
     print();//输出缓冲区情况
     index_out++;
     pthread_mutex_unlock(&mutex);
     sem_post(&empty);
   }
if(sum==0)
exit(0);
}
int main()
{
 int i;
 printf("输入生产者个数:");
   scanf("%d",&PRODUCER);
   printf("输入消费者个数:");
   scanf("%d",&CONSUMER);
   printf("输入缓冲区个数:");
   scanf("%d",&BUFFER);
   printf("输入每个生产者生产产品的个数:");
   for(i=1;i<PRODUCER+1;i++){
   scanf("%d",&k[i]);
   sum+=k[i];
   }
   printf("\n");
   int rthread[18];
   pthread_t producer[PRODUCER];//生产者
   pthread_t consumer[CONSUMER];//消费者

   int sinit1=sem_init(&empty,0,BUFFER);//初始化同步信号量
   int sinit2=sem_init(&full,0,0);
   int minit =pthread_mutex_init(&mutex,NULL);//初始化互斥信号量

   if(sinit1 && sinit2)
   {
         printf("信号量初始化失败 /n");
     exit(1);
   }
   if(minit)
   {
     printf("信号量初始化失败 /n");
     exit(1);
   }
   for(i=0;i<PRODUCER;i++)//创建生产者线程
   {
      rthread[i]=pthread_create(&producer[i], NULL, Producer, NULL);

      if(rthread[i])
      {
          printf("生产者 %d 创建失败 /n", i);
          exit(1);
      }
                                                            
  }
   for(i=0;i<CONSUMER;i++)//创建消费者线程
   {
      rthread[i]=pthread_create(&consumer[i], NULL, Consumer,NULL);

   if(rthread[i])
      {
          printf("消费者 %d 创建失败 /n", i);
          exit(1);
      }
   }
   for(i=0;i<PRODUCER;i++)//销毁生产者线程
   {
      pthread_join(producer[i],NULL);
   }
   for(i=0;i<CONSUMER;i++)//销毁生产者线程
   {
      pthread_join(consumer[i],NULL);
   }
   exit(0);
}



在这里插入图片描述在这里插入图片描述在这里插入图片描述

  • 3
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
func (c *cAsset) CreatComponent(r *ghttp.Request) { var req *v1.CreateComponentReq if err := r.Parse(&req); err != nil { r.Response.WriteJson(g.Map{ "code": 1, "msg": err.Error(), }) } createRequest := &creativecomponent.CreateRequest{ AdvertiserID: req.AdvertiserID, } res, err := service.Asset().Create(createRequest) if err != nil { r.Response.WriteJson(g.Map{ "code": 2, "msg": err.Error(), }) } r.Response.WriteJson(res) }这段代码中creativecomponent.CreateRequest的过滤条件为type CreateRequest struct { // AdvertiserID 广告主ID AdvertiserID uint64 `json:"advertiser_id,omitempty"` // ComponentInfo 组件信息 ComponentInfo *ComponentInfo `json:"component_info,omitempty"` },其中ComponentInfo为type ComponentInfo struct { // ComponentID 组件ID ComponentID model.Uint64 `json:"component_id,omitempty"` // ComponentType 组件类型 ComponentType enum.ComponentType `json:"component_type,omitempty"` // ComponentName 组件名称。长度小于等于20。一个中文长度为2 ComponentName string `json:"component_name,omitempty"` // ComponentData 组件详细信息。不同的component_type对应的值不同,具体的结构见创建或更新接口定义 ComponentData ComponentData `json:"component_data,omitempty"` // CreateTime 创建时间。格式"2020-12-25 15:12:08" CreateTime string `json:"create_time,omitempty"` // Status 组件审核状态。 Status enum.ComponentStatus `json:"status,omitempty"` }想要把ComponentInfo作为参数放到createRequest中,该怎么做?请详一点
07-20
要将ComponentInfo作为参数放入createRequest中,你可以按照以下步骤进行修改: 首先,你需要在CreateComponentReq结构体中添加一个ComponentInfo字段,用于接收组件信息,如下所示: ```go type CreateComponentReq struct { AdvertiserID uint64 `json:"advertiser_id" v:"required" dc:"广告主id"` ComponentInfo *ComponentInfo `json:"component_info,omitempty"` } ``` 接下来,在CreateRequest结构体中将ComponentInfo字段的类型更改为*ComponentInfo,如下所示: ```go type CreateRequest struct { AdvertiserID uint64 `json:"advertiser_id,omitempty"` ComponentInfo *ComponentInfo `json:"component_info,omitempty"` } ``` 然后,你可以根据实际需求创建一个ComponentInfo结构体,并将其作为参数传递给createRequest。以下是示例代码: ```go func (c *cAsset) CreatComponent(r *ghttp.Request) { var req *v1.CreateComponentReq if err := r.Parse(&req); err != nil { r.Response.WriteJson(g.Map{ "code": 1, "msg": err.Error(), }) } // 创建ComponentInfo结构体 componentInfo := &creativecomponent.ComponentInfo{ ComponentID: model.Uint64(123), // 组件ID ComponentType: enum.ComponentType("example"), // 组件类型 ComponentName: "Example Component", // 组件名称 // 具体的组件详细信息,根据实际情况进行填充 ComponentData: creativecomponent.ComponentData{ // ... }, CreateTime: "2022-01-01 10:00:00", // 创建时间 Status: enum.ComponentStatus("pending"), // 组件审核状态 } createRequest := &creativecomponent.CreateRequest{ AdvertiserID: req.AdvertiserID, ComponentInfo: componentInfo, // 将ComponentInfo作为参数赋值给createRequest } res, err := service.Asset().Create(createRequest) if err != nil { r.Response.WriteJson(g.Map{ "code": 2, "msg": err.Error(), }) } r.Response.WriteJson(res) } ``` 在上述示例中,我们创建了一个ComponentInfo结构体,并将其作为参数赋值给createRequest的ComponentInfo字段。你可以根据实际情况填充ComponentInfo结构体中的字段。请确保在填充ComponentData字段时,根据组件类型进行相应的赋值。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值