C++通過C庫或互斥和條件變數實現訊號量
阿新 • • 發佈:2021-07-30
C++標準庫中並沒有訊號量的實現和封裝,我們可以用C語言提供的`
C提供的庫
C++利用互斥和條件變數實現訊號量
訊號量是用來實現對共享資源的同步訪問機制,其使用方法和條件變數類似,都是通過主動等待和主動喚醒來實現的。
C++標準庫中並沒有訊號量的實現和封裝,我們可以用C語言提供的<semaphore.h>
庫
C提供的庫<semaphore.h>
詳解和使用
#include <semaphore.h> //先引入庫 class Foo { private: sem_t sem_1, sem_2; //定義需要的訊號量 public: Foo() { sem_init(&sem_1, 0, 0), sem_init(&sem_2, 0, 0); //初始化訊號量 } void first(function<void()> printFirst) { printFirst(); sem_post(&sem_1); //v操作,使變數加1 } void second(function<void()> printSecond) { sem_wait(&sem_1); printSecond(); sem_post(&sem_2); } void third(function<void()> printThird) { sem_wait(&sem_2); printThird(); } };
互斥和條件變數實現訊號量
1、訊號量
訊號量是一個整數count,提供兩個原子(atom,不可分割)操作:P操作和V操作
- P操作(wait操作):count減1;如果 count < 0 那麼掛起執行的執行緒
- V操作(signal操作):count加1;如果 count <= 0 那麼喚醒一個執行執行緒
2、訊號量實現(定義一個類)
#include <iostream> #include <thread> #include <mutex> #include <condition_variable> using namespace std; class semaphore { public: semaphore(int value = 1) : count(value) {} void wait() { unique_lock<mutex> lck(mtx); if (--count < 0) //資源不足掛起執行緒 cv.wait(lck); //第一次呼叫時後面第二個引數預設為false,之後為true } void signal() { unique_lock<mutex> lck(mtx); if (++count <= 0) //有執行緒掛起,喚醒一個 cv.notify_one(); } private: int count; mutex mtx; condition_variable cv; };
3.利用訊號量解決吃水果問題
吃水果問題:桌子有一隻盤子,只允許放一個水果,父親專向盤子放蘋果,母親專向盤子放桔子 兒子專等吃盤子的桔子,女兒專等吃盤子的蘋果。只要盤子為空,父親或母親就可以向盤子放水果, 僅當盤子有自己需要的水果時,兒子和女兒可從盤子取出。請給出四個人之間的同步關係,並用 pv操作實現四個人的正確活動的問題。
semaphore plate(1), apple(0), orange(0); void father() { while (true) { plate.wait(); cout << "往盤中放一個蘋果" << endl; apple.signal(); } } void mother() { while (true) { plate.wait(); cout << "往盤中放一個橘子" << endl; orange.signal(); } } void son() { while (true) { orange.wait(); cout << "兒子吃橘子" << endl; plate.signal(); } } void daughter() { while (true) { apple.wait(); cout << "女兒吃蘋果" << endl; plate.signal(); } } int main() { thread f(father), m(mother), s(son), d(daughter); f.join(); m.join(); s.join(); d.join(); return 0; }