本質:計數器 + 等待佇列 + 向外提供的使執行流阻塞 / 喚醒的功能介面
實現同步的原理:程序獲取臨界資源之前,要先獲取訊號量資源;
實現互斥的原理:乙個程序獲取了該臨界資源之後,另乙個程序無法再訪問該臨界資源。(0/1計數器)
對資源進行計數,統計當前的資源數量,通過自身的計數,就可以進行條件判斷,是否能夠進行操作,若不能獲取資源,則阻塞當前執行流。
在程式初始化階段,根據實際資源數量初始化訊號量計數器數值,在每次獲取資源之前,先獲取訊號量(先去判斷計數是否大於0,若大於0,則計數-1,直接返回,獲取資料;否則阻塞當前執行流)
其它執行流生產乙個資源後,先判斷計數器是否 <0 ,若小於0,則喚醒乙個執行流,然後進行計數 +1
介面介紹:
sem_t sem;
intsem_init
(sem_t *sem,
int pshared,
int value)
;//初始化操作
//pshared:這個引數決定了當前的訊號量用於程序間還是執行緒間:0-執行緒間 !0-程序間
//value:實際的資源數量,用於初始化訊號量計數器初值
intsem_wait
(sem_t *sem)
;//阻塞操作---若沒有資源則直接阻塞
intsem_post
(sem_t *sem)
;//喚醒操作
intsem_destroy
(sem_t *sem)
;//銷毀操作
**實現:
#include
#include
#include
#include
#include
#define queue_max 5
class
ringqueue
~ringqueue()
bool
push
(int data)
bool
pop(
int*data)
private
: std::vector<
int> _queue;
//陣列 vector需要初始化節點數量
int _capacity;
//佇列的容量
int _step_read;
//獲取資料的位置下標
int _step_write;
//寫入資料的位置下標
sem_t _lock;
//這個訊號量用於實現互斥
//這個訊號量用於對空閒時間進行計數
//---對於生產者來說空閒空間計數 >0 的時候才能寫資料 --- 初始為節點個數
sem_t _sem_idle;
//這個訊號用於對具有資料的空間進行計數
//---對於消費者來說有資料的空間計數 >0 的時候才能取出資料 --- 初始為0
sem_t _sem_data;};
void
*thr_productor
(void
*arg)
return
null;}
void
*thr_customer
(void
*arg)
return
null;}
intmain()
ret =
pthread_create
(&ctid[i]
,null
, thr_customer,
(void*)
&queue);if
(ret !=0)
}for
(i =
0; i <
4; i++
)return0;
}
Linux 基於訊號量的生產者消費者模型
不是用一般佇列作為緩衝區,而是用環形佇列作為緩衝區 不使用pthread mutex,而使用訊號量來實現生產者消費者的同步。使用的是posix訊號量而不是之前的system v,因為這兩個訊號量作用相同,都用於同步操作,但posix可以用於執行緒間同步。這裡可以暫時把訊號量當成乙個計數器,當值未1時...
訊號量(生產者和消費者模型)
訊號量和管程都是作業系統用於同步提供的兩種方法,我們將結合生產者與消費者模型對此進行學習。為了提高系統的併發性,我們引入了多程序,多執行緒,但是這樣子帶來了資源競爭,也就是多個程式同時訪問乙個共享資源而引發的一系列問題,因此我們需要協調多執行緒對與共享資源的訪問,在任意時刻保證只能有乙個執行緒執行臨...
生產者 消費者模型之訊號量
訊號量 1 定義訊號量 sem t semaphore 定義乙個名為semaphore的訊號量 2 初始化訊號量 int sem init sem t sem,int pshared,unsigned int value 引數 sem t sem 要初始化的訊號量 int pshared pshar...