微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

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

生产者消费者

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因为只生产不消费不能发生同步。

原文地址:https://www.jb51.cc/wenti/3281092.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐