经典的进程同步问题

经典的进程同步问题

普通版:一类进程作为生产者,生产产品,生产的产品放入一个缓冲区,消费者从缓冲区中取出产品,需要保证生产者不可以向满的缓冲区中添加产品,消费者不可以从空的缓冲区中取出产品。同一时刻只可以有一个生产者生产产品或者消费者消费产品。

升级版可以实现同一个时刻既有生产者生产产品,又有消费者消费产品。但是绝对不可以同一时刻多个生产者生产产品或者多个消费者消费产品。同时使用count记录缓冲区中产品的数量。

  • 生产者消费者问题

    1)生产者进程和消费者进程都以异步方式运行, 但它们之间必须保持同步。

    2)可利用互斥信号量$mutex$实现诸进程对缓冲池的互斥使用(不可以同时既向缓冲区中放入数据,又从缓冲区中拿出数据);利用资源信号量empty和full分别表示缓冲池中空缓冲池和满缓冲池的数量。 假定这些生产者和消费者相互等效

    /*
    in表示放入数据的地址,out表示取出数据的地址
    buffer[n]:表示大小为n的缓冲池(由多个缓冲区组成) 
    mutex,mutex1,mutex2:互斥型信号量,初值为1
    empty,full:资源型信号量,empty表示空缓冲区的数量,full表示满缓冲区的数量
    item:表示一个数据项
    */
    Int in=0,out=0;  
    Item buffer[n];   
    Semaphore mutex1=1,mutex2 = 1,empty=n,full=0;  //生产者
    Void producer(){ do{生产一个产品放入nextp;/** 进入区* 先申请资源信号量,在申请互斥信号量* mutex1控制同一个时间段内只能有一个生产者生产产品*/wait(empty);wait(mutex1);/*临界区*/buffer[in]=nextp;in=(in+1) % n;/*退出区*/signal(mutex1);signal(full);/*对计数器count的互斥访问*/wait(mutex);count++;signal(mutex);}while(TRUE)
    }//消费者
    Void consumer(){ do{/*进入区*/wait(full);wait(mutex2);     //消费者对缓冲区的互斥访问/*临界区*/nextc =buffer[out];          //只有一份out =(out+1) mod n;/*退出区*/signal(mutex2);signal(empty);/*对计数器count的互斥访问*/wait(mutex);count--;signal(mutex);消费 nextc中的产品;                        }while(TRUE)
    }Void main(){cobeginproceducer();consumer();coend
    }

    注意:

    1)每个程序的互斥操作wait()和signal()必须成对的出现。

    2)输入进程不可以向满的缓冲池中输入数据,计算进程不可以从空的缓冲池中取数据

    3)在每个程序中的多个wait操作顺序不能颠倒,必须先执行对资源信号量的wait操作,在进行对互斥信号量的wait操作,否则可能引起进程死锁。

    4)可以使用三个互斥信号量mutex、mutex1、mutex2实现同一时刻既有生产者生产,又有消费者消费。

  • 读者—写着问题

    该问题涉计两类进程,第一类进程是读进程Reader,另一类进程是写进程Writer,多个读进程可以同时读一个文件(共享资源),多个写的进程不可以同时写一个文件(对写互斥),并且读的时候不能写,写的时候不能读(对读互斥)。

    1)问题核心:保证一个Writer进程必须与其他进程互斥地访问共享对象的同步问题。

    2)只要求读文件的进程称为“Reader进程”,其它进程则称为“Writer进程”。

    3)允许多个进程同时读一个共享对象,但不允许一个Writer进程和其他Reader进程或Writer进程同时访问共享对象(共享对象并不是临界资源,因为他允许多个进程对其访问)

    /*
    记录型信号量解决读者—写者问题rmutex:读进程对Readcount的互斥
    wmutex:writer对reader和writer的互斥
    readcount:表示正在读的进程数目,只有当readcount=0的时候才需要申请wmutex权限,大于0的时候不需要
    */semaphore rmutex=1, wmutex =1;
    int readcount =0;
    Void Reader(){do{wait(rmutex);          //防止多个reader进程对readcount的访问if (Readcount==0){    //如果readcount不等于0,表示有进程正在进行读操作,绝对没有写操作wait(wmutex);}Readcount ++;signal(rmutex);…读;…wait(rmutex);Readcount - -;if (Readcount==0){      //只有等于0的时候才需要释放资源,使得写进程可以工作signal(wmutex);}signal(rmutex);}while(TRUE);
    }
    Void writer(){do{wait(wmutex);      //申请写权限的资源写;signal(wmutex);}while(TRUE);
    }Void main(){cobeginreader();  writer();Coend
    }

    利用信号量集的机制实现读者-写者问题

    int RN;
    semaphore L = RN;             //表示读者的数量
    mx = 1;						//对写者进行互斥的访问void Reader(){while(true){Swait(L, 1, 1);         //申请一个读者进程Swait(mx, 1, 0);       //判断当前是否有写者进程在写,该出相当于一个开关operation...Ssignal(L, 1);}
    }void Writer(){while(true){//此处首先申请一个mx,如果当前系统中无写者进程,则该语句必定执行成功,Reader进程中的//Swait(mx, 1, 0)便处于关闭状态,只需要等系统中的读进程执行完毕,(L, RN,0)执行成//功,打开开关即可。Swait(mx, 1, 1; L, RN, 0);operation...;//释放一个写进程Ssignal(mx, 1);}
    }void main(){cobeginReader();Writer();coend;
    }

     

  • 哲学家的进餐问题

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

    /*
    记录型信号量解决问题
    */
    //每一只筷子均为临界资源
    semaphore chopstick[5]={1,1,1,1,1};
    //所有的信号量均被初始化为1,第i位哲学家的活动可描述为:
    do{wait(chopstick[i]);          //拿左手的筷子wait(chopstick[(i+1) mod 5] );      //拿右手的筷子…eat;…signal(chopstick[i]);    //放左手signal(chopstick[(i +1)mod 5]);       //放右手…think;
    }while(TRUE);

    存在的问题:假如五位哲学家同时饥饿而各自拿起左边的筷子时,就会使五个信号量chopstick均为0,当他们再试图去拿右边的筷子时,都将因无筷子可拿而无限等待。进入死锁状态。

    解决办法:

    **1)**至多只允许有四位哲学家同时去拿左边的筷子,最终能保证至少有一位哲学家能够进餐,并在用毕后释放出他用过的两只筷子,从而使更多的哲学家能够进餐。

    semaphore chopstick[5]={1,1,1,1,1};
    semaphore count=4;
    void philosopher(int i)
    {while(true){think();wait(count); //请求进入房间进餐wait(chopstick[i]); //请求左手边的筷子wait(chopstick[(i+1)%5]); //请求右手边的筷子eat();signal(chopstick[(i+1)%5]); //释放右手边的筷子signal(chopstick[i]); //释放左手边的筷子signal(count); //退出房间释放信号量}
    }

    **2)**仅当哲学家的左右两只筷子均可用时,才允许他拿起筷子进餐。

    /*
    使用AND型信号量解决,本质当同时拥有两只筷子的时候才允许拿起筷子进餐
    */
    semaphore chopstick[5]={1,1,1,1,1};
    Philosopher i
    do{think;Swait(chopstick[(i+1)mod 5],chopstick[i ]);     //同时分配两只筷子eat;Ssignal(chopstick[(i+1)mod 5], chopstick[i ] );     //同时放下两只筷子  
    }while(TRUE)

    **3)**规定奇数号哲学家先拿他左边的筷子,然后再去拿右边的筷子;偶数号哲学家则相反。

    semaphore chopstick[5]={1,1,1,1,1};
    //第i 位哲学家的活动可描述为:
    do{//奇数位哲学家先拿左手的筷子if  i mod 2=1 {wait(chopstick[ i ]);wait(chopstick[ ( i +1) mod 5] )}//偶数位哲学家先拿右手边的筷子else{wait(chopstick[ ( i +1) mod 5] );wait(chopstick[ i ])}eat;signal(chopstick[ i ]);signal(chopstick[(i +1)mod 5]);…think;
    }while(TRUE)

     

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/445118.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

面试题汇总---深度学习(图像识别,NLP内容)

文章目录1.基本概念1.1 为什么神经网络中深度网络的表现比广度网络表现好?1.2 推导BP算法1.3 什么是梯度消失和梯度爆炸?1.4 常用的激活函数有哪些?1.5 常用的参数更新方法有哪些?1.6 解决过拟合的方法?数据层面模型层…

Linux-2.6.25 TCPIP函数调用大致流程

Linux-2.6.25 TCPIP函数调用大致流程学习目的,随手笔记。函数和文字说明会不断补充更新。Changelog2008.10.08 最近找工作忙。暂时缓缓插口层系统调用sendsys_sendsys_sendtosendtosys_sendtosock_sendmsgsendmsgsys_sendmsgsock_sendmsgwritesys_writevfs_write…

Python(28)-文件,os模块

文件1. 文件2. 文件的基本操作3. 读取文件open()3.1 文件指针: 标记从哪一个位置开始读取数据.3.2 文件的打开方式mode3.3 文件按行读取3.3.1 readline()3.3.2 readlines()4.文件输出f.write(),print()5.文件复制5.1 小文件复制(搬家)5.2 大文件复制&…

IOCP的程序

C代码 #include <winsock2.h> #include <mswsock.h> #include <windows.h> #include <stdio.h> #include <stdlib.h> #include <assert.h> #include "vld.h" #pragma message("automatic link to ws2_32.lib and…

PaperNotes(3)-图像分割-RCNN-FCN-Boxsup

图像分割算法对比小结1.{基本概念}2.{R-CNN}2.1R-CNN 网络结构选择性搜索算法为什么选择SVM作分类器边框回归2.2{R-CNN 训练}2.3{R-CNN实验结果}2.4{R-CNN语义分割}2.5{补充材料}2.5.1{R-CNN建议区域放缩}2.5.2{IOU阈值设置不一样的原因}2.5.3{Bounding-box回归修正}2.6{R-CNN存…

Python模块(3)--PIL 简易使用教程

PIL模块-用与记1.图片导入Image.open()2.图像显示.show()4.查看图片属性.format,.size,.mode3.图像格式转换.convert()4.图像模式“L”&#xff0c;“RGB”,"CYMK"5. 图片旋转.rotate()旋转方式1&#xff1a;旋转不扩展旋转方式2&#xff1a;旋转扩展旋转方式3&#…

日志级别 debug info warn eirror fatal

日志级别 debug info warn eirror fatal 软件中总免不了要使用诸如 Log4net, Log4j, Tracer 等东东来写日志&#xff0c;不管用什么&#xff0c;这些东东大多是大同小异的&#xff0c;一般都提供了这样5个日志级别&#xff1a; Debug Info Warn Error Fatal一个等级比一个高&…

输入输出系统

I/O设备&#xff1a;输入输出和存储功能的设备 I/O设备的分类 按传输的速度&#xff1a; 低速设备&#xff08;如键盘、鼠标、语音输入输出设备&#xff09; 中速设备&#xff08;如行式打印机、激光打印机等&#xff09; 高速设备&#xff08;如磁带机、磁盘机、光盘机等&…

vue2源码解析---v-model双向数据绑定

什么是v-model v-model 是 Vue 中的一个指令&#xff0c;用于实现表单元素与 Vue 实例中数据的双向绑定。这意味着当表单元素的值发生变化时&#xff0c;Vue 实例中的数据也会随之更新 工作原理 生成ast树 本质上是语法糖 结合了v-bind和v-on两个指令 示例代码 new Vue({e…

php收集的精典代码

1. οncοntextmenu"window.event.return&#xff06;#118aluefalse" 将彻底屏蔽鼠标右键 <table border οncοntextmenureturn(false)><td>no</table> 可用于Table 2. <body onselectstart"return false"> 取消选取、防止复制…

python外卷(7)--glob

glob模块1.glob.glob()2.对比os.listdir()glob是python自带的一个操作文件的模块&#xff0c;可用于查找 指定路径 中 匹配的 文件。1.glob.glob() 下面是一个测试文件路径&#xff1a; (base) pppp-System-Product-Name:~/Desktop/test_glob$ tree . ├── a │ ├── 1…

Sublime Text 2配置强大的IDE开发环境,运行java

Sublime Text 2是我无意中发现的、据说十分强大的、便捷的编辑器&#xff0c;许多程序员都投入到Sublime Text 2的怀抱中。 1 配置java开发环境的方法如下&#xff1a; 在jdk安装目录下的bin文件夹下新建一个bat格式的文件&#xff0c;文件命为javacexec.bat。 如果是在Wind…

thinkphp的快捷方法实例化对象

D、F、S、C、L、A、I 他们都在functions.php这个文件家 下面我分别说明一下他们的功能 D&#xff08;&#xff09; 加载Model类 M&#xff08;&#xff09; 加载Model类 A&#xff08;&#xff09; 加载Action类 L&#xff08;&#xff09; 获取语言定义 C&#xff08;&#xf…

Python外卷(8)--pdist, squareform

pdist, squareform1.pdist, squareform使用例子2.通过矩阵的四则运算实现上述pdist, squareformscipy.spatial.distance 距离计算库中有两个函数&#xff1a;pdist, squareform&#xff0c;用于计算样本对之间的欧式距离&#xff0c;并且将样本间距离用方阵表示出来。&#xff…

模拟进程调度

功能 data.h #ifndef _Data_h_ #define _Data_h_#include <stdio.h> #include <stdlib.h> #include <string.h>#define ElemType PCB #define Status int #define OK 1 #define ERROR 0 #define TimeSlice 1 #define Infinity 10 //INT_MAX#define NAME_M…

gdb调试多进程和多线程命令

1. 默认设置下&#xff0c;在调试多进程程序时GDB只会调试主进程。但是GDB&#xff08;>V7.0&#xff09;支持多进程的 分别以及同时 调试&#xff0c;换句话说&#xff0c;GDB可以同时调试多个程序。只需要设置follow-fork-mode(默认值&#xff1a;parent)和detach-on-fork…

python外卷(10)--取整

"取整"那些事1.python 内置函数1.1int()--向下取整1.2round()--四舍五入2.math模块取整函数2.1 math.floor()--向下取整2.2 math.ceil()--向上取整2.3 math.modf()--分别取小数部分和整数部分3.numpy模块取整函数3.1 numpy.floor()--向下取整3.2 numpy.ceil()--向上取…

模拟银行家算法

介绍 data.h #ifndef _Data_h_ #define _Data_h_#include <stdio.h> #include <stdlib.h> #include <string.h>#define ElemType PCB #define Status int #define true 1 #define false 0 #define OK 1 #define ERROR 0 #define RESOURCE_NUM …

Lua 与 C混合编程 .

本文通过程序实例说明C调用lua脚本和lua调用C的方法: 先建立一个 test.c文件: #include <stdio.h> #include <stdlib.h> #include "lua.h" #include "lualib.h" #include "lauxlib.h" #pragma comment(lib, "lua5.1.lib&qu…

模拟固定分区分配

介绍 data.h #ifndef _Data_h_ #define _Data_h_#include <stdio.h> #include <stdlib.h> #include <string.h> #define LIST_INIT_SIZE 10 #define LISTINCREMENT 2 #define true 1 #define false 0 #define PCBType PCB #define Status int…