訊號量應用場景總結

2021-07-09 18:41:37 字數 3287 閱讀 3312

如果在共享記憶體中有併發的操作,即多個程序同時往同一塊共享記憶體寫東西,就會出錯,例如兩個併發程序,同時操作共享記憶體(往其寫),會在中途出錯。詳見

現在就用訊號量來保護共享記憶體,這裡為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...