基於訊號量的生產者與消費者模型

2021-10-08 16:41:36 字數 1962 閱讀 6389

本質:計數器 + 等待佇列 + 向外提供的使執行流阻塞 / 喚醒的功能介面

實現同步的原理:程序獲取臨界資源之前,要先獲取訊號量資源;

實現互斥的原理:乙個程序獲取了該臨界資源之後,另乙個程序無法再訪問該臨界資源。(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...