【操作系统】之进程(线程)同步

生产者消费者主要解决----同步

生产者消费者

1、信号量的考虑

这里使用3个信号量,其中两个信号量 empty 和 full 分别用于解决生产者和消费者线程之间的同步问题, mutex 是用于这两个线程之间的互斥问题。其中 empty 初始化为 N (缓冲区的空单元数), mutex 初始化为1, full初始化为0。

2、流程图

  • 开始→建立有名管道→打开有名管道→初始化三个信号量→创建消费者和生产者两个线程

  • 生产者线程: wait 操作( empty )→ wait 操作( mutex )→读管道→ signal 操作( full )→ signal 操作( mutex )

  • 消费者线程: wait 操作( full )→ wait 操作( mutex )→写管道→ signal 操作( empty )→ signal 操作( mutex )

3.编译

gcc tongbu -o -lpthread -lpthread//线程库

4.代码

 #include<string.h>
 #include<stdio.h>
 #include<stdlib.h>
 #include<unistd.h>
 #include<pthread.h>
 #include<errno.h>
 #include<sys/ipc.h>
 #include<semaphore.h>
 #include<fcntl.h>
 ​
 #define FIFO "myfifo"
 #define N 5
 ​
 int lock_var;
 time_t end_time;
 char buf_r[100];
 sem_t mutex,full,empty;
 int fd;//文件操作符
 ​
 void productor(void * arg);//生产者
 void consumer(void * arg);//消费者
 ​
 int main(int argc,char * argv[])
 {
     pthread_t id1,id2;//线程标识符
     pthread_t mon_th_id;
     int ret;
     end_time=time(NULL)+3;//程序运行时间
     
     if((mkfifo(FIFO,O_CREAT|O_EXCL)<0)&&(errno!=EEXIST))
         printf("cannot creat fifoserver\n");
     printf("Preparing for reading bytes \n");
     memset(buf_r,0,sizeof(buf_r));//把buf_r清0,附上大小
     
     fd=open(FIFO,O_RDWR|O_NONBLOCK,0);
     if(fd==-1)
     {
         perror("open");
         exit(1);
     }
     ret=sem_init(&mutex,0,1);//信号量初始化
     ret=sem_init(&empty,0,N);
     ret=sem_init(&full,0,0);
     if(ret!=0)
     {
         perror("sem_init");
     }
     ret=pthread_create(&id1,NULL,(void*)productor,NULL);//线程创建(参数1:线程标识符,2:空,3:线程实体,4:空)
     if(ret!=0)
         perror("pthread cread1");
     ret=pthread_create(&id2,NULL,(void*)consumer,NULL);
     if(ret!=0)
         perror("pthread cread2");
     pthread_join(id1,NULL);//等待线程结束
     pthread_join(id2,NULL);
     exit(0);
 }
 ​
 ​
 void  productor(void * arg)
 {
     int i,nwrite;
     while(time(NULL)<end_time)
    {
         sem_wait(&empty);
         sem_wait(&mutex);
         if((nwrite=write(fd,"hello",5))==-1)
    {  
         if(errno==EAGAIN)
         printf("The FIFO has not been read yet,please try later\n ");
    }
         else
             printf("write hello to the FIFO\n");
         sem_post(&full);
         sem_post(&full);
         sem_post(&mutex);
         sleep(1);
    }
 }
 ​
 ​
  void consumer(void *arg)
 {
     int nolock=0;
     int ret,nread;
     while(time(NULL)<end_time)
     {
         sem_wait(&full);
         sem_wait(&mutex);
         memset(buf_r,0,sizeof(buf_r));
         if ((nread=read(fd,buf_r,100))==-1)
         { 
             if(errno==EAGAIN)
                 printf("no data yet\n");
         }
         else
             printf("read %s from FIFO\n",buf_r);
         sem_post(&empty);
         sem_post(&mutex);
         sleep(1);
     }
 }
 运行结果:
     Preparing for reading bytes 
     write hello to the FIFO
     read hello from FIFO
     write hello to the FIFO
     read hello from FIFO
     write hello to the FIFO
     read hello from FIFO

如果把 ret=pthread_create(&id1,NULL,(void*)consumer,NULL);改成 ret=pthread_create(&id1,NULL,(void*)productor,NULL);,结果只会是 Preparing for reading bytes因为只生产不消费不能发生同步。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

编程远泊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值