同步的概念
- 協(xié)調(diào)多線(xiàn)程對(duì)共享數(shù)據(jù)的訪(fǎng)問(wèn)
- 任何時(shí)刻只能有一個(gè)線(xiàn)程執(zhí)行臨界區(qū)代碼
信號(hào)量
是操作系統(tǒng)提供的一種協(xié)調(diào)共享資源訪(fǎng)問(wèn)的方法。
- OS是管理者,地位高于進(jìn)程
- 用信號(hào)量表示系統(tǒng)資源的數(shù)量
信號(hào)是一種抽象數(shù)據(jù)類(lèi)型
- 由一個(gè)整形(sem)變量和兩個(gè)原子操作組成
- P操作:
a. sem減1;
b. 如sem<0,進(jìn)入等待,否則繼續(xù) - V操作:
a. sem加1;
b. 若sem <=0,喚醒一個(gè)等待進(jìn)程
信號(hào)量的特性:
- 信號(hào)量是被保護(hù)的整數(shù)變量
a. 初始化完成后,只能通過(guò)P和V操作修改
b. 由操作系統(tǒng)保證PV為原子操作 - P可能被阻塞,V不會(huì)被阻塞
- 通常信號(hào)量是”公平的“
a. 線(xiàn)程不會(huì)被無(wú)限期阻塞在P操作
b. 假定信號(hào)量等待按隊(duì)列順序
信號(hào)量的實(shí)現(xiàn):
class Semaphore{
int sem;
WaitQueue q;
}
Semaphore::P(){
sem --;
if(sem < 0){
Add this thread t to q;
block(t);
}
}
Semaphore::V(){
sem ++;
if(sem <= 0){
Remove a thread t from q;
wakeup(t);
}
}
信號(hào)量的分類(lèi):
- 二進(jìn)制信號(hào)量:資源數(shù)目為0或1
- 資源信號(hào)量:資源數(shù)目為任何非負(fù)數(shù)
信號(hào)量的使用:
- 互斥訪(fǎng)問(wèn):臨界區(qū)的互斥訪(fǎng)問(wèn)控制
每類(lèi)資源設(shè)置為一個(gè)信號(hào)量,其初始值為1
mutex = new Semaphore();
mutex->P();
Critical Section;
mutex->V();
必須成對(duì)使用PV操作
P操作保證互斥訪(fǎng)問(wèn)臨界資源
V操作保證使用后釋放臨界資源
PV操作不能次序錯(cuò)誤,重復(fù)或遺漏
- 條件同步:線(xiàn)程間的事件等待
條件同步設(shè)置一個(gè)信號(hào)量,其初始值為0
conditon = new Semaphore(0);
假設(shè)線(xiàn)程A和B同時(shí)在執(zhí)行,若要滿(mǎn)足A在執(zhí)行N操作前,線(xiàn)程B必須要完成X操作
線(xiàn)程A
....M....
conditon->P();
....N....
線(xiàn)程B
....X....
conditon->V();
....Y....
如上,若線(xiàn)程A先于線(xiàn)程B執(zhí)行,那么執(zhí)行到P操作,會(huì)被阻塞,直到線(xiàn)程B
完成X操作,執(zhí)行V,信號(hào)量為1,這時(shí)A才可以繼續(xù)執(zhí)行下去。
管程
管程是一種用于多線(xiàn)程互斥訪(fǎng)問(wèn)共享資源的程序結(jié)構(gòu)
a. 采用面向?qū)ο蠓椒ǎ?jiǎn)化了線(xiàn)程間的同步控制。
b. 任一時(shí)刻最多只有一個(gè)線(xiàn)程執(zhí)行管程代碼。
c. 正在管程中的線(xiàn)程可臨時(shí)放棄管理的互斥訪(fǎng)問(wèn),等待事件出現(xiàn)時(shí)恢復(fù)管程的使用
a. 在對(duì)象/模塊中,收集相關(guān)共享數(shù)據(jù)
b. 定義訪(fǎng)問(wèn)共享數(shù)據(jù)的方法管程的組成
a. 一個(gè)鎖:控制管理代碼的互斥訪(fǎng)問(wèn)
b. 0或多個(gè)條件變量:管理共享數(shù)據(jù)的并發(fā)訪(fǎng)問(wèn)
管程
條件變量
- 條件變量是管程內(nèi)的等待機(jī)制
a. 進(jìn)入管程的線(xiàn)程因資源被占用而進(jìn)入等待狀態(tài)
b. 每個(gè)條件變量表示一種等待原因,對(duì)應(yīng)一個(gè)等待隊(duì)列 - Wait操作
a. 將自己阻塞在等待隊(duì)列中
b. 喚醒一個(gè)等待者或釋放管程的互斥訪(fǎng)問(wèn) - Signal操作
a. 將等待隊(duì)列中的一個(gè)線(xiàn)程喚醒
b. 如果等到隊(duì)列為空,則等同空操作
條件變量的實(shí)現(xiàn):
Class Condition{
int numWaiting = 0;
WaitQueue q;
}
Condition::Wait(lock){
numWaiting ++;
Add this thread t to q;
release(lock);
schedule();
require(lock);
}
Condition::Signal(){
if(numWaiting > 0){
Remove a thread t from q;
wakeup(t);
numWaiting --;
}
}