進化版的互斥鎖(1 --> n)
由於互斥鎖的粒度比較大,如果我們希望在多個執行緒間對某一物件的部分資料進行共享,使用互斥鎖是沒有辦法實現的,只能將整個資料物件鎖住。這樣雖然達到了多執行緒操作共享資料時保證資料正確性的目的,卻無形中導致執行緒的併發性下降。執行緒從並行執行,變成了序列執行。與直接使用單程序無異。
訊號量,是相對折中的一種處理方式,既能保證同步,資料不混亂,又能提高執行緒併發。
sem_init函式
sem_destroy函式
sem_wait函式
sem_trywait函式
sem_timedwait函式
sem_post函式
以上6 個函式的返回值都是:成功返回0,失敗返回-1,同時設定errno。(注意,它們沒有pthread字首)
sem_t型別,本質仍是結構體。但應用期間可簡單看作為整數,忽略實現細節(類似於使用檔案描述符)。
sem_t sem; 規定訊號量sem不能 < 0。標頭檔案
訊號量基本操作:
sem_wait: 1. 訊號量大於0,則訊號量-- (模擬pthread_mutex_lock)
| 2.訊號量等於0,造成執行緒阻塞
對應sem_post: 將訊號量++,同時喚醒阻塞在訊號量上的執行緒 (模擬pthread_mutex_unlock)
但,由於sem_t的實現對使用者隱藏,所以所謂的++、--操作只能通過函式來實現,而不能直接++、--符號。
訊號量的初值,決定了占用訊號量的執行緒的個數。
sem_init函式
初始化乙個訊號量
int sem_init(sem_t *sem, int pshared, unsigned int value);
參1:sem訊號量
參2:pshared取0用於執行緒間;取非0(一般為1)用於程序間
參3:value指定訊號量初值
sem_destroy函式
銷毀乙個訊號量
int sem_destroy(sem_t *sem);
sem_wait函式
給訊號量加鎖 --
int sem_wait(sem_t *sem);
sem_post函式
給訊號量解鎖 ++
int sem_post(sem_t*sem);
sem_trywait函式
嘗試對訊號量加鎖 -- (與sem_wait的區別模擬lock和trylock)
int sem_trywait(sem_t *sem);
sem_timedwait函式
限時嘗試對訊號量加鎖 --
int sem_timedwait(sem_t *sem, const struct timespec*abs_timeout);
參2:abs_timeout採用的是絕對時間。
定時1秒:
time_tcur = time(null); 獲取當前時間。
struct timespec t; 定義timespec 結構體變數t
t.tv_sec= cur+1; 定時1秒
t.tv_nsec= t.tv_sec +100;
sem_timedwait(&sem, &t); 傳參
/*訊號量實現 生產者 消費者問題*/
#include
#include
#include
#include
#include
#define num 5
int queue[num]; //全域性陣列實現環形佇列
sem_t blank_number, product_number; //空格子訊號量, 產品訊號量
void *producer(void *arg)
}void *consumer(void *arg)
}int main(int argc, char *argv)
執行緒訊號量同步
thread sem.c include include include include define thread number 3 define repeat number 3 define delay time levels 10.0 sem t sem thread number void ...
執行緒同步 訊號量
執行緒同步方法 訊號量不常用,找到個帖子不錯,記錄一下!依賴的標頭檔案 include 函式宣告 sem t 表示訊號量 int sem init sem t sem,int pshared,unsigned int value 名稱 sem init 功能 initialize an unname...
執行緒同步 訊號量
上篇文章 執行緒同步 睡覺與喚醒 遺留了乙個問題,就是會出現死鎖的情況。所以為了解決這個問題,又要引入乙個新的同步概念,那就是訊號量。起初我個人在理解的時候陷入了乙個奇怪的圈子,就總憑感覺和名字認為這個訊號量是不是乙個儲存我之前失效訊號的容器,讓後在需要之前訊號的時候在重新呼叫訊號。其實沒有那麼複雜...