首页 > 系统相关 >5.经典进程同步问题

5.经典进程同步问题

时间:2023-12-20 17:12:14浏览次数:37  
标签:哲学家 进程同步 signal 筷子 chopstick 问题 经典 缓冲区 wait

  1. 生产者消费者问题

    一组生产者进程和一组消费者进程共享一个初始为空,大小为n的缓冲区。当缓冲区没满时,生产者才能把消息放入缓冲区,否则必须等待,只有缓冲区不空时,消费者才能从中取出消息,否则必须等待。由于缓冲区是临界资源,它只允许一个生产者放入消息,或一个消费者从中取出消息。

    semaphore mutex=1; //临界区互斥信号量
    semaphore empty=n; //空闲缓冲区
    semaphore full=0; //满缓冲区
    int in=0,out=0;
    item buffer[n];
    
    //生产者
    producer()
    {
    	while(1){
             produce an item nextp; //生产产品
    		wait(empty); //获取空缓冲区
    		wait(mutex); //进入临界区
    		buffer[in]=nextp; //数据放入临界区
    		in=(int+1)%n; 
    		signal(mutex);  //离开临界区,释放互斥信号量
    		signal(full);  //满缓冲区数+1
    	}
    }
    
    //消费者
    consumer()
    {
    	while(1){
    		wait(full); //获取满缓冲区
    		wait(mutex); //进入临界区
    		nextc=buffer[out]; //从缓冲区取数据
    		out=(out+1)%n;
    		signal(mutex); //离开临界区,释放互斥信号量
    		signal(empty); //空缓冲区数+1
             consume the item in nextc; //消费产品
    	}
    }
    
  2. 读者写者问题

    有读写两组进程,共享一个文件,

    ①多个读者可同时访问文件

    ②但多个写者不能同时访问文件

    ③写者和读者不能同时访问文件

    semaphore rmutex=1; //保护counter变量的互斥信号量
    semaphore wmutex=1; //保证读者和写者互斥访问文件
    int counter=0;  //记录当前读者数量
    
    //读者
    reader(){
        while(1){
            wait(rmutex);  //互斥访问counter变量
            if(counter==0)wait(wmutex);  //当第一个读者时,阻止写进程写
            couter++;  //计数器+1
            signal(rmutex);  //释放互斥变量counter
            
            reading  //读操作 
                
            wait(rmutex);  //互斥访问counter变量
            counter--;  //计数器-1
            if(counter==0)signal(wmutex); //当最后一个读者时,允许写进程写
            signal(rmutex);  //释放互斥变量counter
        }	
    }
    
    
    
    //写者
    writer(){
    	while(1){
            wait(wmutex);  //互斥访问共享文件
            writing  //写操作
            signal(wmutex);	//释放共享文件
    	}
    }
    
    
    
  3. 哲学家就餐

    有五个哲学家围在一张圆桌,分别坐在周围的五张椅子上,在圆桌上有五个碗和五只筷子,他们的生活方式是交替的进行思考和进餐。平时,一个哲学家进行思考,饥饿时便试图取用其左右最靠近他的筷子,只有在他拿到两支筷子时才能进餐。进餐完毕后,放下筷子继续思考。

    • 由问题描述我们可以知道,一共有五个哲学家,也就是五个进程;五只筷子,也就是五个临界资源;因为哲学家想要进餐,必须要同时获得左边和右边的筷子,这就是要同时进入两个临界区(使用临界资源),才可以进餐。
    semaphore chopstick[5] = {1,1,1,1,1}; 		//初始化信号量
    
    void P(){
      while(1)
      {
        think;			//思考
        wait(chopstick[i]);//判断哲学家左边的筷子是否可用
        wait(chopstick[(i+1)%5]);//判断哲学家右边的筷子是否可用
        
        eat;		//进餐
        
        signal(chopstick[i]); //退出临界区,允许别的进程操作缓冲池
        signal(chopstick[(i+1)%5]); //缓冲池中非空的缓冲区数量加1,可以唤醒等待的消费者进程
      }
    }
    
    

    问题:如果考虑到并发问题,五个哲学家同时拿起了左边的筷子,此时,五只筷子立刻都被占用了,没有可用的筷子了,当所有的哲学家再想拿起右边筷子的时候,因为临界资源不足,只能将自身阻塞,而所有的哲学家全部都会阻塞,并且不会释放自己手中拿着的左边的筷子,因此就会一直处于阻塞状态,无法进行进餐并思考。

    解决方法:

    1. 至多只允许有四位哲学家同时去拿左边的筷子,最终能保证至少有一位哲学家能够进餐,并在用餐完毕后能释放他占用的筷子,从而使别的哲学家能够进餐
    2. 仅当哲学家的左、右两支筷子可用时,才允许他拿起筷子
    3. 规定奇数号哲学家先拿他左边的筷子,然后再去拿右边的筷子;而偶数号哲学家则相反

    方法1(增加一个信号量实现):

    semaphore chopstick[5] = {1,1,1,1,1}; 		//初始化信号量
    semaphore sm=4;
    
    void P(){
      while(1)
      {
        think;			//思考
        wait(sm);
        wait(chopstick[i]);//判断哲学家左边的筷子是否可用
        wait(chopstick[(i+1)%5]);//判断哲学家右边的筷子是否可用
        signal(sm);
        
        eat;		//进餐
        
        signal(chopstick[i]); //退出临界区,允许别的进程操作缓冲池
        signal(chopstick[(i+1)%5]); //缓冲池中非空的缓冲区数量加1,可以唤醒等待的消费者进程
      }
    }
    

    方法2(使用AND型信号量):

    semaphore chopstick[5] = {1,1,1,1,1}; 		//初始化信号量
    semaphore sm=4;
    
    void P(){
      while(1)
      {
        think;			//思考
        wait(chopstick[i],chopstick[(i+1)%5]); //判断哲学家左右筷子是否同时可用
        
        eat;
        signal(chopstick[i],chopstick[(i+1)%5]); //进餐完毕,释放哲学家占有的筷子
      }
    }
    

    方法3(添加判断来决定获取左、右筷子的顺序,规定偶数号哲学家先拿左手筷子,再拿右手筷子):

    semaphore chopstick[5] = {1,1,1,1,1}; 		//初始化信号量
    semaphore sm=4;
    
    void P(){
      while(1)
      {
        think;			//思考
        if(i%2==0){
        	wait(chopstick[i]); //判断哲学家左边的筷子是否可用
        	wait(chopstick[(i+1)%5]); //判断哲学家右边的筷子是否可用
    	}
    	else{
        	wait(chopstick[(i+1)%5]);  //判断哲学家右边的筷子是否可用
        	wait(chopstick[i]); //判断哲学家左边的筷子是否可用
    	}
        
        eat;
        signal(chopstick[i]); //释放左边筷子
       signal(chopstick[(i+1)%5]); //释放右边筷子
      }
    }
    

标签:哲学家,进程同步,signal,筷子,chopstick,问题,经典,缓冲区,wait
From: https://www.cnblogs.com/zzmxj/p/17916999.html

相关文章

  • 智能监测/检测系统/摄像头监控系统EasyCVR大华云台控制问题的解决方法
    GB28181视频集中存储/云存储/视频监控管理平台EasyCVR能在复杂的网络环境中,将分散的各类视频资源进行统一汇聚、整合、集中管理,实现视频资源的鉴权管理、按需调阅、全网分发、智能分析等。AI智能大数据视频分析EasyCVR平台已经广泛应用在工地、工厂、园区、楼宇、校园、仓储等场景......
  • 4.进程同步与互斥
    生产者消费者问题一组生产者进程和一组消费者进程共享一个初始为空,大小为n的缓冲区。当缓冲区没满时,生产者才能把消息放入缓冲区,否则必须等待,只有缓冲区不空时,消费者才能从中取出消息,否则必须等待。由于缓冲区是临界资源,它只允许一个生产者放入消息,或一个消费者从中取出消息。......
  • formatter 和 scope 冲突不能同时使用失效问题
    formatter 和scope冲突不能同时使用否则就会失效解决办法:自己写 formatter方法:<divv-else-if="item.prop==='file_size'"><spanv-html="formatter(scope.row.file_size,item.prop)"></span></div> methods:{formatte......
  • 下载图片中文乱码问题解决记录
    1.问题背景需求需要做一个场所码下载的需求,后端接口实现使用的是AWT[1]。在本地Windows开发环境联调接口一切正常,当部署到测试环境Linux服务器上之后,前端同事反馈下载的图片如下:这个问题其实不能算是乱码,而是字体缺失,图片中的汉字使用了微软雅黑字体,而测试环境使用的是docker部......
  • 密码学家晚餐问题(n>2情况)
    密码学家晚餐问题场景描述三位密码学家(Alice、Bob、Carol)正在享受晚餐,坐在他们钟爱的三星级餐馆。业务逻辑在准备支付账单时,侍者通知他们需要匿名支付,其中一个密码学家可能正在支付账单。账单可能已经由美国国家安全局(NSA)支付。他们互相尊重匿名支付的权利,但又需要确认是否是N......
  • 详解十大经典排序算法(五):归并排序(Merge Sort)
    算法原理归并排序的核心思想是将一个大的数组分割成多个小的子数组,然后分别对这些子数组进行排序,最后将排序后的子数组合并起来,得到一个有序的大数组。算法描述归并排序(MergeSort)是一种经典的排序算法,其原理基于分治(DivideandConquer)策略。它的核心思想是将一个大问题分割成多个......
  • 详解十大经典排序算法(四):希尔排序(Shell Sort)
    算法原理希尔排序是一种基于插入排序的排序算法,也被称为缩小增量排序。它通过将待排序的序列分割成若干个子序列,对每个子序列进行插入排序,然后逐步缩小增量,最终使整个序列有序。算法描述希尔排序(ShellSort)是一种基于插入排序的算法,由DonaldShell于1959年提出。它是插入排序的一种......
  • C++聊天集群服务器解决客户端注销登录问题
    客户端如何处理注销登录问题?问题描述:​ 在客户端登录后进行注销选择,然后重新登录刚才注销的账号,直接卡死。注意这是概率发生,因为是主线程和子线程抢服务器发送的信息,只有子线程抢到才会发生卡死问题产生原因分析:​ 前置条件:主线程循环等待用户输入选择(第一张图是死循环,send......
  • 阿里云ECS自建K8S_IPV6重启后异常问题解决过程
    阿里云ECS自建K8S_IPV6重启后异常问题解决过程背景最近安装了一个单节点的K8S_IPV6昨天不知道何故突然宕机了.然后只能在阿里云的控制台后台重启了ECS启动之后看K8S的状态一开始是正常的.但是查看ing的时候,发现IP地址却变成了IPV4的地址,感觉比较奇怪.这里整理一下......
  • VMware Ubuntu虚拟机打开报错问题
    问题描述昨天虚拟机卡死,我把VMwareWorkstation的进程用任务管理器杀掉了,今天重新打开虚拟机却发现以下报错报错内容另一个程序已锁定文件的一部分,进程无法访问打不开磁盘“E:\VMware\Linux\ubuntu-18.04.6\ubuntu-18.04.6.vmdk”或它所依赖的某个快照磁盘。模块“Disk”启......