同步與互斥是程序間的制約關係,
同步:是為了保證臨界資源的時序的可控性,安全性。是程序間由於相互合作引起的直接制約關係。
互斥:是為了保證對臨界資源同一時間的唯一訪問性。是程序間由於共享資源引起的間接制約關係。
多個程序當需要操作同一資源的時候就需要通過同步和互斥機制來實現對臨界資源的安全訪問。
臨界資源就是:一次只允許乙個程序訪問的資源。
從本質上來講訊號量是乙個有等待佇列的計數器。這就很想我們去一件很火的餐廳吃飯,需要牌號等位一樣。
從訊號量的實現角度講,訊號量就是乙個結構體型別的資料變數。是對系統中資源和其組織情況的抽象。
結構體中有兩個成員:
value:當該值 >0 標誌現在有幾個空閒的可用資源,初值是一共有幾個可用資源。
當 =0 標誌資源整合用完
當 <0 該值的絕對值標誌現在有幾個等待該類資源的程序,對應著阻塞佇列的長度。
l:阻塞佇列,是等待該資源的程序pcb錶鏈。該佇列的長度物件value<0時的絕對值,此時在該佇列的程序都處於阻塞狀態。
訊號量也是程序間通訊的方式一種。也就是說訊號量本事也是乙個臨界資源,為了保證其安全我們規定訊號量的操作是原子操作,也就是說該操作不可被打斷。要不不做,要不必須完成。
p操作:是申請資源的過程。
1.value的值自減減,使用的共有操作,所以復用寫在前面:value–
2.系統判斷value的值是否 >=0:
1).是》=0:表示有空閒可以訪問,進入臨界區訪問臨界資源。
2).否<0:表示沒有空閒,則讓權從執行轉入阻塞狀態,在阻塞佇列中標記
v操作:是釋放資源的過程。
1.value的值自加加:value++
2.系統判斷value的值是否<=0:
1).否》0:此時沒有多餘程序阻塞等待。
2).是<=0:有程序等待,喚醒阻塞佇列的第乙個程序,使其由阻塞到就緒狀態。
3.該程序可以繼續執行訪問剩餘區(非臨界區),若執行完,則讓權釋放cpu。
同步:由乙個無條件執行的程序開始,訊號量資源初始值為0,該程序結束進行v(s)操作,訊號量資源+1,此時會通知別的程序。需要該資源的程序,打破阻塞,p(s)操作,去訪問臨界資源。
互斥:p(s)操作,資源-1,則其餘程序不可再訪問該份臨界資源。使用完v(s)操作,資源+1,此時別的程序才可進行是否可以訪問判斷。
1.建立訊號量
system v標誌的訊號量,可以建立的時候建立乙個集合及多個訊號量
#include #include #include int semget(key_t key, int nsems, int sem***);
//key值做訊號量的標識,nsems指定一次建立多少個訊號量
//sem*** 是建立許可權,ipc_create
//返回檔案識別符號
2.設定訊號量初值
訊號量的初值只能設定一次。
int semctl (int semid,int semnum,int cmd,...);
//semid 操作控制代碼 semnum 指定要操作幾個訊號量,
//cmd具體的操作(setval設定單個訊號量初值,setall設定所以訊號量初值,semnum的值會被忽略)
//... 不定引數,這裡是乙個結構體獲取訊號量資訊,乙個聯合獲取訊號量的值 。
union semun ;
3.在對臨界資源操作前,先獲取訊號量-1操作
//semid 控制代碼,
//struct sembuf, containing the following members:
// unsigned short sem_num; /* 訊號量集合中的訊號量編號,0代表第1個訊號量 */
// short sem_op;
/*若op>0進行v操作訊號量值加op,表示程序釋放控制的資源*/
/*若op<0進行p操作訊號量值減o'p*/
// short sem_***;
/* 設定訊號量的預設操作,ipc_nowait設定訊號量操作不等待*/
/*sem_undo 選項會讓核心記錄乙個與呼叫程序相關的undo記錄,如果該程序崩潰,則根據這個程序的undo記錄自動恢復相應訊號量的計數值*/
struct sembuf buf;
buf.sem_num = 0;
buf.sem_op = -1;
buf.sem_*** = sem_undo;
semop(id, &buf, 1);
4.對臨界資源操作完成後,釋放資源,訊號量+1操作
//semid 控制代碼,
//struct sembuf, containing the following members:
//unsigned short sem_num; /* semaphore number */
// short sem_op; /* semaphore operation */
// short sem_***; /* operation flags */
struct sembuf buf;
buf.sem_num = 0;
buf.sem_op = 1;
buf.sem_*** = sem_undo;
semop(id, &buf, 1);
5.使用完訊號量對其進行刪除操作
int semctl (int semid,int semnum,int cmd,...);
//刪除也是使用semctl只不過cmd的具體操作是ipc_rmid
程序間同步之訊號量
概念 訊號量是乙個特殊的變數,程式對其訪問都是原子操作,且只允許對它進行等待 即p 訊號變數 和傳送 即v 訊號變數 資訊操作。最簡單的訊號量是只能取0和1的變數,這也是訊號量最常見的一種形式,叫做二進位制訊號量。而可以取多個正整數的訊號量被稱為通用訊號量。二值訊號量 訊號量的值只有0和 1,若資源...
程序間同步 訊號量集
一 建立或者開啟訊號量 int semget key t key,int nsems,訊號量集中訊號量的個數 int flag 開啟 0,建立 ipc creat 0644 返回值 返回訊號量集的識別符號 檢視訊號量 ipcs s 具體案例 include include include inclu...
linux程序間同步之POSIX訊號量
閱讀linux系統程式設計手冊筆記 posix訊號量跟system v訊號量一樣,都是用於程序和執行緒同步對同享資源的訪問。訊號量 posix,system v 是乙個整數,其值是不能小於0的。posix訊號量主要分為 命名訊號量 未命名訊號量。首先先介紹命名訊號量。先來看看命名訊號量的主要api ...