四大經典同步問題

2022-04-06 05:19:35 字數 3901 閱讀 7604

一組生產者程序和一組消費者程序共享乙個初始為空,大小為n的緩衝區,只有緩衝區沒滿時,生產者才能把訊息放入緩衝區,否則必須等待,只有緩衝區不空時,消費者才能從中取出訊息,否則必須等待。由於緩衝區是臨界資源,它只允許乙個生產者放入訊息或乙個消費者從中取出訊息。

關係分析

生產者和消費者對緩衝區訪問都是互斥訪問(生產者之間互斥,避免資料覆蓋;消費者之間互斥,避免資料重複消費;生產者和消費者之間互斥)。同時,生產者和消費者之間也是相互協作的關係,只有生產者生產之後,消費者才能消費,屬於同步關係。

訊號量設定

設定兩個同步訊號量:full=0,表示初始滿緩衝區個數為0個,empty=n,表示初始空緩衝區個數為n個。

設定乙個互斥訊號量:mutex,初值為1,用於控制對緩衝區的互斥訪問。

生產者生產之前判斷是否有空餘緩衝區,生產乙個訊息之後,

**示例

semaphore mutex = 1;

semaphore empty = n;

semaphore full = 0;

producer()

}consumer()

}

這種情形,比較簡單,找到同步和互斥關係,然後設定好相應的訊號量,根據情況賦予初值即可(互斥訊號量初值肯定為1)。每次申請資源前,執行p操作,每次釋放資源後,執行v操作。

桌子上有乙個盤子,每次只能向其中放入乙個水果。爸爸專向盤子中放蘋果,媽媽專向盤子中放橘子,兒子專等吃盤子中的橘子,女兒專等吃盤子中的蘋果。只有盤子為空時,爸爸或媽媽才可向盤子中放乙個水果;僅當盤子中有自己需要的水果時,兒子或女兒可以從盤子中取出。

關係分析

每次只能向盤子中放入乙個水果,爸爸和媽媽是互斥關係。爸爸和女兒,媽媽和兒子是同步關係,而且這兩對程序必須連起來,兒子和女兒之間沒有互斥或同步關係,因為他們是選擇條件執行,不可能併發。

訊號量設定

設定乙個互斥訊號量:plate=1,用於保證爸爸和媽媽互斥訪問盤子

**示例

dad()

}mom()

}son()

}daughter()

}這是生產者-消費者模型的公升級版,本質上是兩組生產者和消費者。問題的關鍵是生產者之間的互斥,生產者和消費者之間的同步連續執行。

比如爸爸和女兒在生產之後都沒有立即釋放盤子,而是釋放對應的水果,這樣兒子和女兒都可以訪問盤子,但是只有有相應水果的消費者才可以順利進行消費,然後釋放盤子。

兒子和女兒訪問盤子都沒有p(plate),因為他們不需要對盤子進行互斥訪問,兩個消費者是選擇條件執行。

找到這個關鍵點即可。

有讀者和寫者兩組併發程序,共享乙個檔案,當兩個或以上的讀程序同時訪問共享資料時,不會產生***,但若某個寫程序和其他程序(讀程序或寫程序)同時訪問共享資料時則可能導致資料不一致的錯誤。因此要求:①允許多個讀者可以同時對檔案進行讀操作;②只允許乙個寫者向檔案中寫資訊;③任一寫者在完成寫操作之前不允許其他讀者或寫者工作;④寫者執行寫操作前,應讓已有的讀者和寫者全部退出。

關係分析

讀者和寫者是互斥的,寫者和寫者也是互斥的,但是讀者和讀者不存在互斥問題。

寫者比較好處理,和任何程序都是互斥的,用互斥訊號量的p操作和v操作即可解決。讀者的問題比較複雜,需實現與寫者互斥的同時,實現與其他讀者的同步。

可以引入乙個計數器(普通變數,而非記錄型訊號量,也不是整型訊號量,只用於統計讀者程序數量),用於記錄當前讀者的數量,如果讀者數為0,則需要判斷是否可以互斥訪問,如果讀者數大於0,則說明當前不存在寫者,可以直接訪問。

但是對於計數器的修改也需要互斥進行,所以需要額外引入乙個互斥訊號量,使用者保護計數器的修改。

訊號量設定

設定兩個互斥訊號量:

mutex=1用於實現計數器(普通變數)的修改,

rw=1用於實現讀者和寫者對檔案的互斥訪問

**示例

int count=0;

semaphore mutex=1;

semaphore rw=1;

writer()

}reader()

}

在上面的演算法中,讀程序是具有優先權的,只有一直有讀程序在,寫程序就有可能被餓死。只有讀程序都執行完了,寫程序才有機會訪問檔案。

演算法改進

當有讀者正在訪問檔案時,如共有寫程序請求訪問,這時應禁止後續讀者的請求,等到已在共享檔案的讀者執行完畢,立即讓寫者執行。只有在無寫者執行的情況下,才允許讀者再次執行。

**示例

int count=0;

semaphore mutex=1;

semaphore rw=1;

semaphore w=1;

writer()

}reader()

}

這個演算法對於寫者來說還是不太公平的,如果共享檔案已經有很多讀者在訪問了,這個時候新來的寫者必須等這些讀者全都執行完了之後才可以訪問共享檔案。但是這個演算法改進了讀者一直占用共享檔案的問題,只要寫者程序到來,就可以占用w,使得後續的讀程序被阻塞。

一張圓桌上,5名哲學家,每兩名哲學家之間有一根筷子。哲學家需拿起兩根筷子才可以進餐,否則等待。

關係分析

每名哲學家與左右鄰居對筷子的訪問是互斥的

思路有兩種解決辦法:

1.同時拿起兩根筷子

2.對每個哲學家拿起筷子的動作指定規則,避免飢餓和死鎖發生

訊號量設定

定義互斥訊號量陣列chopstick[5]=,用於對5個筷子的互斥訪問。哲學家按序編號0-4,哲學家i左邊筷子的編號為i,右邊筷子的編號為(i+1)%5

**示例

semaphore chopstick[5]=;

pi()while(1);

}

這個演算法存在乙個問題,當5個哲學家都要進餐,並且都拿起了左邊的筷子時,所有程序都無法獲取右邊的筷子,全部阻塞等待其他哲學家釋放筷子,造成死鎖。

為防止死鎖產生,可以加一些限制條件:

①至多執行4名哲學家同時進餐,這個時候即使4個哲學家都拿起了左邊的,但是第五根筷子可以被其中乙個哲學家拿起,然後正常推進。

②僅當哲學家能夠同時拿起左右兩根筷子時,才允許他拿起筷子

③對哲學家順序編號,奇數號先拿左邊再拿右邊,偶數號相反。

**示例

semaphore chopstick[5]=;

semaphore mutex=1; //保證每次只有乙個哲學家能夠訪問筷子

pi()while(1);

}

不因為有筷子能拿起就拿起,而考慮能否一次性拿起兩根筷子。這是哲學家進餐問題的關鍵。

三個吸菸者,乙個**者。每個吸菸者需要的材料不同,共需要三種材料:菸草,紙,膠水。他們分別只有其中一種,剩下的兩種需要**者提供。**者可以無限的提供三種材料,每次只隨機提供其中的兩種(意味著每次只有乙個吸菸者的材料能夠湊齊)。湊齊材料的吸菸者成功吸菸之後,**者才能繼續提供。

**者和吸菸者屬於同步關係,只有**者**了自己所需要的材料時,吸菸者才可以正常消費。三個吸菸者不能同時吸菸,屬於互斥關係。

設定四個同步訊號量,

offer1=0:第乙個吸菸者需要的材料

offer2=0:第二個吸菸者需要的材料

offer3=0:第三個吸菸者需要的材料

finish=0:吸菸動作完成,**者可以繼續提供

int random;

semaphore offer1=0;

semaphore offer2=0;

semaphore offer3=0;

semaphore finish=0;

//**者

process p1()

supply the material;

p(finish);

}}process p2()

process p3()

process p4()

深度學習四大經典書籍

我們都知道現在機器學習 深度學習的資料太多了,面對海量資源,往往陷入到 無從下手 的困惑出境。而且並非所有的書籍都是優質資源,浪費大量的時間是得不償失的。今天,給大家推薦這四本好書。推薦指數 本書自出版以來收到眾多好評,因為是 keras 作者寫的書,所以全書基本圍繞著 keras 講深度學習的各種...

資料與結構的四大經典演算法思想

解題思路 1.針對一組資料,定義了限制值和期望值,在滿足限制值的情況下,期望值最大 2.每次選擇當前情況下,最對限制值同等貢獻的情況下,對期望值貢獻最大的資料 3.舉幾個例子驗證一下貪心演算法的正確性 在很多情況下貪心演算法並不能給出問題的最優解,因為貪心演算法總是選擇當前情況下最優的解,比如在有權...

快取七大經典問題

1.快取失效 原因分析 在寫快取時,我們一般會根據業務的訪問特點,給每種業務資料預置乙個過期時間,在寫快取時把這個過期時間帶上,讓快取資料在這個固定的過期時間後被淘汰。一般情況下,因為快取資料是逐步寫入的,所以也是逐步過期被淘汰的。但在某些場景,一大批資料會被系統主動或被動從 db 批量載入,然後寫...