9.4.5放棄對信號燈的控製。
函數slgsem導致一個進程放棄對給定的信號燈的控製,並且向等待這個信號燈的所有進程發出這一事實的信號。這個信號燈必須先由進程創建或打開,要更進一步,這個進程必須用函數waitsem或nbwaitsem獲得對這個信號燈的控製。如果遇到錯誤,如企圖取消對一個不存在的信號燈的控製,那麼這個函數就返回-1。
這個函數典型地用在一個進程存取完相應的設備或係統資源之後。這就允許等待著的進程獲得控製。例如,在下麵的這個程序段中,sigsem為信號燈“tty.1”的控製的結束發信號。
這個例子也為一個操作的結束發信號,這個操作將數據拷貝到與由“ftty1”給出的信號燈對應的設備中。
注意,如果一個進程在結束前發控製結束信號失敗了,那麼信號燈會被鎖在這個已終止的進程中。在這樣的情況下,必須用函數creatsem重新設置這個信號燈。
9.4.6程序舉例
這一小節展示怎樣使用信號燈函數控製一個係統資源的存取。下麵的程序創建五個不同的進程,這些進程競爭一個信號燈的控製,每個進程五次請求對於這個信號燈的控製,每次保持控製1秒鍾,接著放棄它。雖然這個程序執行無意義的工作,但是它清楚地解釋了信號燈的使用。
這個程序含有大量的全程變量。數組“semf”包括信號燈的名字,這個名字被creatsem和opensem函數使用;變量“sem—num”是信號燈的編號,這是由creatsem和opensem返回的值,結果用於waitsem和sigsem;最後,變量“holdsem”含有每個進程請求信號燈控製的次數。
程序的主函數使用mktemp(S)函數為信號燈建立一個唯一的名字,然後使用creasem具有的名字創建這個信號燈。一旦創建了信號燈,它就開始創建子進程,這些進程將競爭對這個信號燈的控製。在每個子進程創建後,該子進程就打開這個信號燈,並調用函數doitO。當控製從doito返回時,子進程終止。父進程也調用doito,等待每個子進程的結束,並且最後用unlink(S)函數刪去這個信號燈。
doitO調用waitsem函數請求對信號燈的控製。這個函數一直等到這個信號燈可用為止,然後將一個0到4之間的整數顯示到標準輸出,等待1秒種,再用sigsem(S)函數放棄控製。
這個程序的每一步檢查可能出現的錯誤,如果遇到錯誤,這個程序就調用函數。這個函數顯示一條出錯消息,並終止程序。