// 司機
while(true)
//售票員
while(true)
印表機按照列印佇列執行列印,當列印佇列中有 6個列印任務,2個程序同時新增列印任務,列印佇列的第7個任務是哪個,需要協調
小結
程序有自己的執行條件,有時執行 有時等待,執行完 可能也要 發出訊號,讓等待該訊號的其他程序執行
程序同步 就是 程序有序的執行
//共享資料
#define buffer_size 10 //快取空間
typedef struct item;
item buffer[buffer_size];
intin = out = counter = 0;
//生產者程序
while(true)
//消費者程序
while(true)
多程序配合,需要等待 阻塞
通過 程序的走走停停 來保證 多程序合作的 合理有序
等待是程序同步的核心
//生產者
while(true)
//消費者
while(true)
問題:
有多個生產者,p1生產乙個item,放入緩衝區,緩衝區滿了,p1 sleep
這時,p1 生產乙個item,發現緩衝區已經滿了,p1 sleep
消費者消耗了乙個產品,counter == buffer_size - 1,給消費者發訊號,喚醒p1,p1 wakeup
消費者再消耗乙個產品,counter == buffer_size - 2,p2 不能被喚醒了
解決:
單純依靠counter判斷緩衝區的個數是不夠的,還要知道有多少程序睡眠了
根據訊號量 判斷是否等待,是否執行
訊號量 int sem:
0 或者 負數,說明需要等待,讓其他程序執行
舉例:一種資源的數量是8
訊號量 = 2:有2個資源可以使用
訊號量 = -2,有2個程序在等待資源
上邊生產者消費者的例子:
1.緩衝區滿,p1執行,p1 sleep,sem = -1,表示乙個程序睡眠了
2.p2執行,發現緩衝區滿,p2 sleep,sem = -2,表示2個程序睡眠了
3.消費者c執行,wakeup p1,sem = -1
4.消費者c再執行一次,wakeup p2,sem = 0
5.消費者c再執行一次,sem = 1,消費者程序睡眠
6.p3執行,sem = 0,表示沒有資源了
訊號量:2023年,荷蘭學者dijkstra提出用一種特殊整型變數用來記錄,訊號用來sleep和wakeup
// semaphore ['seməfɔː] n. 訊號
struct semaphore
//消費資源,p來自荷蘭語 proberen,即test
p(semaphore s);
//生產資源,v來自荷蘭語 verhogen,即increment
v(semaphore s);
p(semaphore s)
}v(semaphore s)
}
快取檔案 buffer.txt,操作該快取檔案
同時只能有乙個程序在寫該檔案,定義互斥訊號量mutex(互斥量)
當有程序在操作緩衝區內容時,p(mutex),造成程序等待
使用完 緩衝區檔案,呼叫v(mutex),釋放該檔案資源,其他程序可以操作緩衝檔案了
//用檔案定義 共享緩衝區
int fd = open("buffer.txt");
write(fd, 0, sizeof(int));//寫in
write(fd, 0, sizeof(int));//寫out
//訊號量的定義和初始化
semaphore full = 0;//生產的產品的個數
semaphore empty = buffer_size;//空閒緩衝區的個數
semaphore mutex = 1;//互斥訊號量
//生產者
producer(item)
//消費者
consumer()
程序通訊與程序同步
多個程序可以共享系統中的各種資源,但其中許多資源一次只能為乙個程序使用,我們把一次僅允許乙個程序使用的資源稱為臨界資源。許多物理裝置都屬於臨界資源,如印表機等 對臨界資源的訪問必須互斥進行,在每個程序中,訪問臨界資源的那段 稱為臨界區。程序通訊與同步的目的主要有下面 1 資料傳輸 乙個程序需要將他的...
程序同步與通訊
程序通訊 訊號通訊 硬體 包括硬體異常,除零,越界訪問,這些訊號由核心產生,併發送到相關程序 軟體 某些軟體事件如alarm 函式產生sigalrm訊號,管道通訊產生sigpipe 程序使用kill raise 等函式。訊號的相應方式 忽略訊號,但是有兩個訊號不能忽略,sigkill sigstop...
程序同步與互斥
程序同步與互斥 首先,我們看乙個例子 程序p1 p2公用乙個變數count,初始值為0 p1 p2兩個程序的執行順序是隨機的,p1 p2可能順序執行或交錯執行。由圖可見,不同的執行順序,count值會不同,這是不允許的。在多道程式系統中,由於資源共享或程序合作,使程序間形成間接相互制約和直接相互制約...