linux Posix 訊號量 二

2021-09-06 20:34:00 字數 2579 閱讀 3963

一、posix訊號量

1.posix訊號量分為兩種:

1.   有名訊號量:使用posix ipc名字標識(有名訊號量總是既可用於執行緒間的同步,又可以用於程序間的同步)

2.   記憶體訊號量:存放在共享記憶體區中(基於記憶體的訊號量則必須在建立時指定成是否在程序間共享,且在所有程序的共享記憶體區,具有隨程序的持續性)

posix訊號量不必在核心中維護(system v訊號量由核心維護),由可能為路徑名的名字來標識。

(posix訊號量更常用於程序間同步,互斥鎖常用於執行緒間同步)

2.基本操作:

1.   建立(create):指定初始值。

2.   等待(wait):如果值小於等於0則阻塞,否則將其減一,又稱p操作。

3.   掛出(post):將訊號量的值加1,加後如果值大於0,則喚醒乙個阻塞在等待上的執行緒,又稱v操作。

二值訊號量可用於互斥,就像互斥鎖一樣。但互斥鎖必須由鎖住它的執行緒解鎖,訊號量的掛出卻不必由執行過等待的同一執行緒執行。

訊號量的wait和post與條件變數的wait和signal類似,區別是:因為永久的改變了訊號量的值,訊號量的操作總被記住(會影響到後續的操作);條件變數的signal如果沒有執行緒在等待,該訊號將丟失(對後續操作沒有影響)。

互斥鎖是為上鎖而優化的,條件變數是為等待優化的,訊號量既可以上鎖也可以等待,因此開銷更大。

3.posix訊號量操作

有名訊號量:

記憶體訊號量:

sem_open

sem_init:需要指定是否共享

sem_wait:原子的「測試並減1」操作

sem_trywait

sem_post:同步技巧中唯一能在訊號處理函式內安全呼叫的操作

sem_getvalue

sem_close

sem_destroy

sem_unlink

即使當前沒有程序開啟訊號量,它的值仍然保持,因此posix有名訊號量至少是隨核心持續的。

在父程序中開啟的任何訊號量,fork後在子程序中仍開啟。

關於posix有名訊號量使用的幾點注意

1、有名訊號量使用sem_unlink從系統中刪除。每個訊號量有乙個引用計數器記錄當前的開啟次數,sem_unlink必須等待這個數為0時才能把name所指的訊號量從檔案系統中刪除。也就是要等待最後乙個sem_close發生。

2、彼此無親緣關係的程序間需使用訊號量時,一般用有名訊號量。如果不需要使用關聯名字時,可改用記憶體訊號量。

記憶體訊號量需要放在共享記憶體區中,並由sem_init函式初始化為shared狀態才能被不同程序使用,這種情況下它的持續性與共享記憶體區相同。sem_init總是初始化訊號量的值,因此,對於乙個給定的訊號量,必須小心保證只呼叫sem_init一次。

3、我們可以用sem_wait來申請共享資源,sem_wait函式可以測試所指定訊號量的值,如果該值大於0,那就將它減1並立即返回。我們就可以使用申請來的共享資源了。如果該值等於0,呼叫執行緒就被進入睡眠狀態,直到該值變為大於0,這時再將它減1,函式隨後返回。sem_wait操作必須是原子的。sem_wait和sem_trywait的差別是:當所指定訊號量的值已經是0時,後者並不將呼叫執行緒投入睡眠。相反,它返回乙個eagain錯誤。

當乙個執行緒使用完某個訊號量時,它應該呼叫sem_post來告訴系統申請的資源已經用完。本函式和sem_wait函式的功能正好相反,它把所指定的訊號量的值加1,然後喚醒正在等待該訊號量值變為正數的任意執行緒。

4、.posix有名訊號量的值是隨核心持續的。也就是說,乙個程序建立了乙個訊號量,這個程序結束後,這個訊號量還存在,並且訊號量的值也不會改變。

5、當持有某個訊號量鎖的程序沒有釋放它就終止時,核心並不給該訊號量解鎖。

posix有名訊號量應用於多執行緒

#include

#include

#include

#include

#include

void *thread_function(void *arg); /*執行緒入口函式*/

void print(pid_t); /*共享資源函式*/

sem_t *sem; /*定義posix有名訊號量*/

int val; /*定義訊號量當前值*/

int main(int argc,char *argv)

sem=sem_open(argv[1],o_creat,0644,3); /*開啟乙個訊號量*/

while(n++<5) /*迴圈建立5個子執行緒,使它們同步執行*/

}pthread_join(a_thread,null);

sem_close(bin_sem);

sem_unlink(argv[1]);

}void *thread_function(void *arg)

void print()

程式用迴圈的方法建立5個執行緒,然後讓它們呼叫同乙個執行緒處理函式thread_function,在函式裡我們利用訊號量來限制訪問共享資源的執行緒數。共享資源我們用print函式來代表,在真正程式設計中它有可以是乙個終端裝置(如印表機)或是一段有實際意義的**。

Linux Posix訊號量 讀寫鎖

posix訊號量 sem t sem init int sem init sem t sem,int pshared,unsigned int value 引數 pshared 0表 示執行緒間共享,非零表 示程序間共享 value 訊號量初始值 sem wait 條件不滿足,等待 sem post...

訊號量 二值訊號量

訊號量 二值訊號量 訊號量是作業系統的重要部分,訊號量一般用來進行資源管理和任務同步。freertos中訊號量分為二值訊號量 互斥訊號量 計數訊號量和遞迴互斥訊號量,應用場景各不同。二值訊號量通常用於互斥訪問或同步,二值訊號量和互斥訊號量非常相似,但互斥訊號量有優先順序,二值訊號量沒有。因此二值訊號...

python訊號量 Python訊號量

python訊號量教程 訊號量是由作業系統管理的一種抽象資料型別,用於在多執行緒中同步對共享資源的使用。本質上說,訊號量是乙個內部資料,用於標明當前的共享資源可以有多少併發讀取。也可以簡單的理解為,訊號量是多把鎖,同時允許多個執行緒來更改資料,而 python訊號量與互斥鎖的關係 訊號量的乙個特殊用...