信號量的實現

信號量的本質是種數據操做鎖,它本不具備數據交換的功能,是經過控制其餘的通訊資源(件,外部設備)來實現進程間通訊它本只是種外部資源的標識。信號量在此過程當中負責數據操做的互斥、同步等功能。 linux

當請求個使信號量來表的資源時,進程須要先讀取信號量的值來判斷資源是否可0,資源能夠請求,等於0,資源可,進程會進睡眠狀態直資源可。 當進程再也不使個信號量控制的共享資源時,信號量的值+1,對信號量的值進的增減 操做均爲原操做,這是因爲信號量主要的做是維護資源的互斥或多進程的同步訪問。 在信號量的建立及初始化上,不能保證操做均爲原性。 數組

1、爲何要使信號量
爲了防出現因多個程序同時訪問個共享資源引起的系列問題,咱們須要種法, 它能夠經過成並使令牌來受權,在任時刻只能有個執線程訪問代碼的臨界區域。 臨界區域是指執數據更新的代碼須要獨佔式地執。信號量就能夠提供這樣的種訪 問機制,讓個臨界區同時間只有個線程在訪問它, 也就是說信號量是來調協進程 對共享資源的訪問的。其中共享內存的使就要到信號量。 緩存

2、信號量的做原理 ide

因爲信號量只能進兩種操做等待和發送信號,即P(sv)和V(sv),他們的爲是這樣的:
P(sv):若是sv的值於零,就給它減1;若是它的值爲零,就掛起該進程的執
V(sv):若是有其餘進程因等待sv被掛起,就讓它恢復運,若是沒有進程因等待sv掛 起,就給它加1. 舉個例,就是兩個進程共享信號量sv,旦其中個進程執了P(sv)操做,它將獲得信號 量,並能夠進臨界區,使sv1。第個進程將被阻進臨界區,由於當它試圖執
P(sv)時, sv0,它會被掛起以等待第個進程離開臨界區域並執V(sv)釋放信號量,這時 第個進程就能夠恢復執。 函數

Linux的信號量機制
Linux提供了組精設計的信號量接來對信號進操做,它們不僅是針對進制信號量,下將會對這些函數進介紹,但請注意,這些函數都是來對成組的信號量值進 操做的。它們聲明在頭件sys/sem.h中。 【信號量的意圖在於進程間同步,互斥鎖和條件變量的意圖則在於線程間同步。可是信號 量也可於線程間,互斥鎖和條件變量也可於進程間。咱們應該使適合具體應的那組原語。】 spa

描述
semctl() semid 標識的信號量集上,或者該集合的第 semnum 個信號量上執 cmd 指定的 控制命令。 (信號量集合索引發始於零。)根據 cmd 不一樣,這個函數有三個或四個參數。當有四個參數時,第四個參數的類型是 union 。調程序必須按照下式定義這個聯合體:
union semun {
int val; // 使的值
struct semid_ds *buf; // IPC_STATIPC_SET 使緩存區
unsigned short *array; // GETALL,SETALL使用的數組線程

Struct seminfo *__buf;//IPC_INFO(linux特有)使用緩存區設計

};orm

注意:該聯合體沒有定義在任何系統頭文件中,所以得用戶本身聲明。<Centos下確實是這樣,可是UNIX下不一樣,不須要本身定義聲明>blog

代碼實現以下:

//sem.h

wKioL1dojADCBFRcAACoUnRPdKo541.png


//sem.c

wKioL1dojB6ymWipAACZWeySXb8778.png

wKiom1dojDCTRegxAACFcq6bFF8500.png

//test.c

wKioL1dojFLx4b0nAABnpRQg5Yk229.png

運行結果以下:

wKioL1dojLOzmiToAAAZ-IGnCkU096.png-wh_50

總結:

信號量的p和v操做都是原子操做,在執行操做時,兩個進程共享一個信號量,兩個進程之間存在互斥關係。

相關文章
相關標籤/搜索