欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

经典同步互斥 ---- 生产者消费者问题

程序员文章站 2022-07-05 09:02:35
...

生产者消费者问题:多个生产者,多个消费者进行同步互斥。把生产信息和消费信息写入.csv文件记录。

//pc.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/shm.h>
#include <sys/ipc.h>
#include <sys/types.h>
#include<sys/sem.h>

#define N 32   //32个货架
#define Prod 7  //生产者7个
#define Cons 5  //消费者5个
#define M_KEY  5201
#define E_KEY  5207
#define F_KEY  5208


int in = 0;   //生产者放产品的位置
int out = 0;   //消费者取产品的位置

int tm = 0;//到达时间

int buf[N] = {0};   //N个货架,开始时初始化为0,没有产品
int mutex,empty,full;  //声明信号量

int id = 0; //生产者消费者id


int P(int sid) //P操作
{
    struct sembuf sb={0,-1,0};
    return semop(sid, &sb, 1);
}
 
int V(int sid) //V操作
{
    struct sembuf sb={0,1,0};
    return semop(sid, &sb, 1);
};



void produce()
{

   FILE *f0;

  char buf[40] = {0}; 
  if(NULL == (f0=fopen("/home/ssm/shiyan2wenjian/pctest.csv","a")))  //打开一个pctest.csv文件
  {
    printf("can not open file\n");
  }
  
  else 
  {
    //printf("put information succed!\n");  //创建成功就输出这句话
	sprintf(buf,"\n生产者%d,%d,丽雅,毛巾,1\n",id,tm);
	//printf("%s", buf);
	fwrite(buf,sizeof(buf),1,f0);//将获取到的字符串写入目标文件

    fclose(f0);  //关闭文件
  }
}

void consume()
{

   FILE *f0;

  char buf[40] = {0}; 
  if(NULL == (f0=fopen("/home/ssm/shiyan2wenjian/pctest.csv","a")))  //打开一个pc.csv文件
  {
    printf("can not open file\n");
  }
  
  else 
  {
    //printf("put information succed!\n");  //创建成功就输出这句话
	sprintf(buf,"\n消费者%d,%d,丽雅,毛巾,1\n",id,tm);
	//printf("%s", buf);
	fwrite(buf,sizeof(buf),1,f0);//将获取到的字符串写入目标文件

    fclose(f0);  //关闭文件
  }
  
}

void* Producer(void *p)  //生产者
{

    P(empty);       //查空货架
      P(mutex);      //申请访问货架区
       id++;
       tm++;
       produce();  //生产
          buf[in]=1;  //放产品
	  in=(in+1)%N;  
	  printf("放置时间%d, 生产者%d, 货架号%d, 金星, 毛巾\n",id,tm,in-1); 
      V(mutex);      //释放货架区      
    V(full);         //发满货架消息     

  
}

void* Consumer(void *p)  //消费者
{

     P(full);            //查满货架
       P(mutex);         //申请访问货架区
         id++;
         tm++;
         buf[out]=0;     //取产品
         out=(out+1)%N;
         printf("取货时间%d, 消费者%d, 货架号%d, 金星, 毛巾\n",id,tm,out-1); 
         consume();       //消费 
       V(mutex);         //释放货架区
     V(empty);           //发空货架消息
       
}



int main(int argc,char *argv[])
{
   pthread_t id1[Prod];  //生产者
   pthread_t id2[Cons];  //消费者
   char keyboard;
   
   int i;
   int ret[Prod];
    
 
    mutex=semget(M_KEY,1,IPC_CREAT|0660);//创建信号量
    semctl(mutex,0,SETVAL,1); //初值1
    
    empty=semget(E_KEY,1,IPC_CREAT|0660);//创建空信号量
    semctl(empty,0,SETVAL,N); //初值N
    
    full=semget(F_KEY,1,IPC_CREAT|0660);//创建满信号量
    semctl(full,0,SETVAL,0); //初值0


    // 创建Prod个生产者线程
    for(i = 0; i < Prod; i++)
    {
       ret[i] = pthread_create(&id1[i], NULL, Producer, (void *)(&i));
       if(ret[i] != 0)
       {
        printf("product%d creation failed \n", i);
        exit(1);
       }
    }
    //创建Cons个消费者线程
    for(i = 0; i < Cons; i++)
    {
       ret[i] = pthread_create(&id2[i], NULL, Consumer, NULL);
       if(ret[i] != 0)
       {
        printf("prochase%d creation failed \n", i);
        exit(1);
       }
    }
      
    

    keyboard=getchar();
    for(i=0;i<Prod; i++)
        pthread_cancel(id1[i]); //终止生产者线程
    for(i=0;i<Cons; i++)
        pthread_cancel(id2[i]); //终止消费者线程
                
    semctl(mutex, 0, IPC_RMID); //删除信号量
    semctl(empty, 0, IPC_RMID); //删除信号量
    semctl(full, 0, IPC_RMID); //删除信号量

    return 0;

}

运行结果如下:
经典同步互斥 ---- 生产者消费者问题

写入的文件数据如下:
经典同步互斥 ---- 生产者消费者问题