經典的進程同步問題

經典的進程同步問題

普通版:一類進程作為生產者,生產產品,生產的產品放入一個緩沖區,消費者從緩沖區中取出產品,需要保證生產者不可以向滿的緩沖區中添加產品,消費者不可以從空的緩沖區中取出產品。同一時刻只可以有一個生產者生產產品或者消費者消費產品。

升級版可以實現同一個時刻既有生產者生產產品,又有消費者消費產品。但是絕對不可以同一時刻多個生產者生產產品或者多個消費者消費產品。同時使用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.pswp.cn/news/445118.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/445118.shtml
英文地址,請注明出處:http://en.pswp.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…