1. 程式人生 > >簡單應用訊號量實現程序同步控制

簡單應用訊號量實現程序同步控制

               --------參考文獻   W.Richard Stevens, Stephen A.Rago.UNIX環境高階程式設計[M].北京:人民郵電出版社,2014.6:455-459.

一、問題引出

1.1 情景模擬

某程序向某個txt檔案寫入"hello",另一程序向該txt檔案讀出已經寫入的"hello"並在螢幕上列印輸出。

毋庸置疑,寫完了才能讀取,讀取完了才能寫入。這兩個程序執行時就需要額外施加同步控制(邊讀邊寫會導致不可預料的後果)。在本情景下,該txt檔案被看成是資源,而且只有一份。

生活中,比較貼切的例子就是列印店的印表機,假設印表機一共有5臺,每臺電腦到底使用哪臺印表機是未知的,因為電腦對任何一臺印表機都沒有特殊要求。印表機就被看成是資源,而且有5份。

舉這個例子是為了說明,資源不是總是隻有1份的,而且申請資源或釋放資源時不總是一份份地申請或釋放。一切都按照實際需求去做

1.2 設計方案

圖1 設計方案

如圖1所示,自主實現的函式用藍色圓角矩形框起來,庫函式用橘色橢圓框起來, 我們實現的,實際上更多的是業務處理,並非底層實現。自主實現的函式內部到最後都會去轉調庫函式(代理)。

1.3 相關知識

semctl包含多種訊號量的操作:

#include<sys/sem.h>
int semctl(int semid, int semnum, int cmd, .../*union semun arg*/);
//返回值實際含義是什麼由引數cmd所指定,在這裡,int不是一個冰冷的數字,而是有豐富含義的。

semid是訊號量集在核心中的編號;semnum是該集合中某個特定訊號量的下標,取值∈[0, nsems-1]cmd是(幻數),代表10種命令的一種(不詳細展開到底是哪10種命令);arg是選項引數,這個引數是一個聯合體,而非指向聯合體的指標。

union semun{
    int val;    //val在引數cmd等於SETVAL時會用到,用於設定成員semnum.semval的值。
    struct semid_ds *buf;    //buf在引數cmd等於IPC_STAT或者IPC_SET時會用到。
    unsigned short *array;    //array在引數cmd等於GETALL或者SETALL時會用到。
};

聯合體semun中出現的semid_ds結構體: 

struct semid_ds{
    struct ipc_perm sem_perm;    //許可權控制。
    unsigned short sem_nsems;    //集合中訊號量的數目。
    time_t sem_otime;    //最後一次呼叫semop()函式的時間。
    time_t sem_ctime;    //最後一次改變本結構體成員值的時間。
    .
    .
    .
};