如果在共享記憶體中有併發的操作,即多個程序同時往同一塊共享記憶體寫東西,就會出錯,例如兩個併發程序,同時操作共享記憶體(往其寫),會在中途出錯。詳見
現在就用訊號量來保護共享記憶體,這裡為p,確保其結果為20000000
訊號量(相當於乙個紅綠燈) 通過這個燈來保護共享資源(讓其它人操作不了)
級別:cpu ,暫存器,一級快取,二級快取(快取相當於高階ram,只是放在cpu裡邊,其訪問速度比ram更快),記憶體,磁碟
原語:即原子操作(例如二進位制開關),作業系統不能被其它指令打斷的一次操作
刪除對應id的訊號量集合:ipcrm -s semid
為了獲得共享資源程序需要執行下列操作: (1
)測試控制該資源的訊號
量。(首先要有個訊號量,即訊號燈,訊號量實際上也有系統維護的資源,有0和1,相當於紅綠燈) (2
)若訊號
量的值為正,則程序可以使用該資源。程序訊號
量值減1
,表示它使用了乙個資源單位。此程序使用完共享資源後對應的訊號
量會加1
。以便其他程序使用。
訊號量只能設定一次
1 使用就減1
0 使用完就加1 (3
)若訊號
量的值為0
,則程序進入休息狀態,直至訊號
量值大於0
。程序被喚醒,返回第(
1)步。
睡眠鎖(普通鎖) 自旋鎖(核心鎖)
為了正確地實現訊號量,訊號量值的測試值的測試及減1操作應當是原子操作(
原子操作是不可分割的,在執行完畢前不會被任何其它任務或事件中斷
)。為此訊號量通常是在核心中實現的(作業系統做的事)。
system vipc機制:訊號量。
ipc:
inter-process communication,程序間通訊
兩個程序(虛擬位址不同)要相加,故兩個程序需要操作同一塊記憶體,不然加不到一起
只能在乙個add函式中設定訊號量初值,這時另乙個函式首先處於等待狀態,即等待另乙個函式進行v操作,它才能進行p操作,從而獲得訊號量
函式原型:
#include
#include
#include
int semget(key_t key,int nsems,int flag);
建立了乙個訊號量,另乙個程序通過key來獲取該訊號量
一次建立不一定只有乙個訊號量,而是乙個訊號量集合
訊號量如果還沒建立,需要先初始化
函式semget建立乙個訊號量集或訪問乙個已存在的訊號量集。返回值:成功時,返回乙個稱為訊號量識別符號的整數,
semop
和semctl
會使用它;出錯時,返回
-1.
引數 key是唯一標識乙個訊號量的關鍵字,如果為ipc_private(這時key的值為0),建立乙個只有建立者程序才可以訪問的訊號量,通常用於父子程序之間;非0值的key(
可以通過
ftok
函式獲得
)表示建立乙個可以被多個程序共享的訊號量。為了將其標識出來,我們用1234;
引數nsems
指定需要使用的訊號量數目。如果是建立新集合,則必須制定
nsems。如果引用乙個現存的集合,則將nsems指定為0。多個訊號量,用於保護多個共享記憶體。需要控制多少個訊號量,nsems就為幾。 引數
flag是一組標誌,其作用與
open函式的各種標誌很相似。它低端的九個位是該訊號量的許可權,其作用相當於檔案的訪問許可權。ipc_creat表示如果不存在該訊號量,則建立它;如果存在,則返回。ipc_excl表示如果該記憶體段存在,則函式返回失敗結果。
這裡的key_t與共享記憶體中的key_t存在於兩個不同的佇列,故其不一樣
int semctl(int semid, int semnum, int cmd, …); 函式
semctl用來直接控制訊號量資訊。函式返回值:成功時,返回
0;失敗時,返回
-1.
引數 semid
是由semget
返回的訊號量識別符號。
引數semnum
為集合中訊號量的編號,當要用到成組的訊號量時,從
0開始。一般取值為
0,表示這是第乙個也是唯一的乙個訊號量。
semun返回訊號的值,從0開始,第乙個訊號量編號為0)(一次中只能獲取乙個值)、setval(根據
semun設定訊號的值,從0開始,第乙個訊號量編號為0)、getall(獲取所有訊號量的值,第二個引數為0,將所有訊號的值存入
semun.array中)、setall(將所有
semun.array的值設定到訊號集中,第二個引數為0)等。
cmd為getval或setval的情況:(這說明訊號量的初始值為0)
引數"…"是乙個聯合體
union semun
(需要由程式設計師自己定義),它至少包含以下幾個成員:
union semun;這是乙個聯合體,說明放引數"…" (放該聯合體)的位置,既可以放乙個陣列位址,可以放乙個結構體陣列位址,還可以在set_val中傳乙個整型值(一般設為1),即放乙個聯合體成員(這裡為4byte),因此可以理解,函式在傳參時,引數的空間才是我們需要注意的,因為函式每次呼叫申請棧空間的時候,首先會先為參量申請空間,再將傳遞的值拷貝到呼叫函式實際申請的棧空間中,即形參相當於區域性變數,每個都需要申請空間,再將形參值拷貝過去
//通常情況僅使用
val,給val
賦值為1
int semop(int semid,struct sembuf *sops,size_t
num_s
ops); 函式
semop用於改變訊號量物件中各個訊號量的狀態。返回值:成功時,返回
0;失敗時,返回
-1.
引數 semid
是由semget
返回的訊號量識別符號。
引數sops
是指向乙個結構體陣列的指標。每個陣列元素至少包含以下幾個成員:
struct sembuf; 引數
nops
為sops
指向的sembuf
結構體 陣列的大小。
加1 or 減1的功能在這個函式中
訊號量需要賦初值,初值必須為正的,這樣才能進行p操作
以下為得到訊號量初始值的函式,arr在這裡為乙個傳入傳出引數,這裡為傳入,將訊號量的初始值放在arr中
而這裡為傳出引數,給訊號量賦值,一般用1,但這裡為了區分,用1,2,3,首先獲取程式中賦予的值,再將其設定到訊號量中
獲取乙個訊號量的狀態
改變訊號量的模式:
訊號量 二值訊號量
訊號量 二值訊號量 訊號量是作業系統的重要部分,訊號量一般用來進行資源管理和任務同步。freertos中訊號量分為二值訊號量 互斥訊號量 計數訊號量和遞迴互斥訊號量,應用場景各不同。二值訊號量通常用於互斥訪問或同步,二值訊號量和互斥訊號量非常相似,但互斥訊號量有優先順序,二值訊號量沒有。因此二值訊號...
python訊號量 Python訊號量
python訊號量教程 訊號量是由作業系統管理的一種抽象資料型別,用於在多執行緒中同步對共享資源的使用。本質上說,訊號量是乙個內部資料,用於標明當前的共享資源可以有多少併發讀取。也可以簡單的理解為,訊號量是多把鎖,同時允許多個執行緒來更改資料,而 python訊號量與互斥鎖的關係 訊號量的乙個特殊用...
訊號 訊號量
訊號是由 系統或者程序傳送給目標程序的資訊,以通知目標程序某個狀態的改變或系統異常。linux訊號可以由如下條件產生 1 對於前台程序,使用者可以通過輸入特殊的終端字元來給它傳送訊號。比如輸入ctrl c通常或給程序傳送乙個中斷訊號 2 系統異常。比如浮點異常和非法記憶體段訪問。3 系統狀態變化 4...