POSIX訊號量和互斥鎖

2021-08-05 19:20:49 字數 3438 閱讀 8192

1 建立訊號量

sem_t *sem_open(const char *name, int oflag);

sem_t *sem_open(const char *name, int oflag, mode_t mode, unsigned int value);

功能:初始化有名訊號量

int sem_init(sem_t *sem, int pshared, unsigned int value);

功能:用於初始化無名的訊號量,注意無名訊號量也可以用於不同程序間的執行緒通訊,這取決於第二個引數,如果pshared非零就可以用於多個程序間通訊,前提是這個無名訊號量存在於共享記憶體區中。

2 刪除訊號量

int sem_close(sem_t *sem);

int sem_unlink(const char *name);

sem_close用於關閉開啟的訊號量。當乙個程序終止時,核心對其上仍然開啟的所有有名訊號量自動執行這個操作。呼叫sem_close關閉訊號量並沒有把它從系統中刪除它,posix有名訊號量是隨核心持續的。即使當前沒有程序開啟某個訊號量它的值依然保持。直到核心重新自舉或呼叫sem_unlink()刪除該訊號量。

3 訊號量p操作

int sem_wait (sem_t *sem);

int sem_timedwait(sem_t *sem, const struct timespec *abs_timeout);

int sem_trywait (sem_t * sem);

1 sem_wait()用於獲取訊號量,首先會測試指定訊號量的值,如果大於0,就會將它減1並立即返回,如果等於0,那麼呼叫執行緒會進入睡眠,指定訊號量的值大於0.

2 sem_trywait和sem_wait的差別是,當訊號量的值等於0的,呼叫執行緒不會阻塞,直接返回,並標識eagain錯誤。

3 sem_timedwait和sem_wait的差別是當訊號量的值等於0時,呼叫執行緒會限時等待。當等待時間到後,訊號量的值還是0,那麼就會返回錯誤。其中 struct timespec *abs_timeout是乙個絕對時間。

4 訊號量v操作

int sem_post(sem_t *sem);

當乙個執行緒使用完某個訊號量後,呼叫sem_post,使該訊號量的值加1,如果有等待的執行緒,那麼會喚醒等待的乙個執行緒。

5 獲取當前訊號量

int sem_getvalue(sem_t *sem, int *sval);

該函式返回當前訊號量的值,通過sval輸出引數返回,如果當前訊號量已經上鎖(即同步物件不可用),那麼返回值為0,或為負數,其絕對值就是等待該訊號量解鎖的執行緒數。

多執行緒程式設計中,(多執行緒程式設計)可以用互斥鎖(也稱互斥量)可以用來保護關鍵**段,以確保其獨佔式的訪問,這有點像二進位制訊號量。posix互斥鎖相關函式主要有以下5個:

#include

int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr);

int pthread_mutex_destroy(pthread_mutex_t *mutex);

int pthread_mutex_lock(pthread_mutex_t *mutex);

int pthread_mutex_trylock(pthread_mutex_t *mutex);

int pthread_mutex_unlock(pthread_mutex_t *mutex);

這些函式第乙個引數mutex指向要操作的目標互斥鎖,成功時返回0,出錯返回錯誤碼

1. pthread_mutex_init用於初始化互斥鎖,mutexattr用於指定互斥鎖的屬性,若為null,則表示預設屬性。除了用這個函式初始化互斥所外,還可以用如下方式初始化:pthread_mutex_t mutex = pthread_mutex_initializer。

2 pthread_mutex_destroy用於銷毀互斥鎖,以釋放占用的核心資源,銷毀乙個已經加鎖的互斥鎖將導致不可預期的後果。

3 pthread_mutex_lock以原子操作給乙個互斥鎖加鎖。如果目標互斥鎖已經被加鎖,則pthread_mutex_lock則被阻塞,直到該互斥鎖佔有者把它給解鎖。

4 pthread_mutex_trylock和pthread_mutex_lock類似,不過它始終立即返回,而不論被操作的互斥鎖是否加鎖,是pthread_mutex_lock的非阻塞版本。當目標互斥鎖未被加鎖時,pthread_mutex_trylock進行加鎖操作;否則將返回ebusy錯誤碼。注意:這裡討論的pthread_mutex_lock和pthread_mutex_trylock是針對普通鎖而言的,對於其他型別的鎖,這兩個加鎖函式會有不同的行為。

5 pthread_mutex_unlock以原子操作方式給乙個互斥鎖進行解鎖操作。如果此時有其他執行緒正在等待這個互斥鎖,則這些執行緒中的乙個將獲得它。

下面是基於訊號量和互斥鎖的生產者消費者模型:

#include#include#include#include#include#include#include#include#include /* for o_* constants */

#include #define err_exit(m) dowhile(0)

#define consumer_count 2

#define producer_count 5

#define buffsize 10

int g_buffer[buffsize];

unsigned int in=0;

unsigned int out=0;

unsigned product_id=0;

unsigned consumer_id=0;

sem_t g_sem_full;

sem_t g_sem_empty;

pthread_mutex_t g_mutex;

pthread_t g_thread[consumer_count+producer_count];

void* consume(void *arg)

printf("in=%d\n",in);

printf("%d thread %d is product %d\n",n,(int)pthread_self(),product_id);

g_buffer[in]=product_id;

in=(in+1)%buffsize;

printf("end produce product %d\n",product_id++);

pthread_mutex_unlock(&g_mutex);

sem_post(&g_sem_empty);

sleep(5);

}}int main()

{ for(int i=0;i

POSIX訊號量實現互斥

採用posix訊號量實現互斥原語,實現執行緒間同步 採用訊號量實現互斥原語 include include include include include include include include include define maxnum 10000 用乙個結構體封裝命名訊號量 struct...

訊號量和互斥鎖

概念 訊號量用在多執行緒多工 同步的,乙個執行緒完成了某乙個動作就通過訊號量告訴別的執行緒,別的執行緒再進行某些動作 大家都在sem wait的時候,就阻塞在那裡 互斥鎖是用在多執行緒多工 互斥的,乙個執行緒占用了某乙個資源,那麼別的執行緒就無法訪問,直到這個執行緒unlock,其他的執行緒才開始可...

訊號量,互斥鎖

注 摘自 程式設計師的自我修養 相關章節。關鍵字 執行緒同步 原子操作 鎖 二元訊號量 訊號量 互斥量 臨界區 讀寫鎖 條件變數 原子操作 共享資料 全域性變數或堆變數 的自增 操作在多執行緒環境下會出現錯誤是因為這個操作 一條c語句 被編譯為彙編 後不止一條指令,因此在執行的時候可能執行了一半就被...