C 中使用條件變數控制線程啟動和暫停

2021-10-24 21:28:07 字數 4457 閱讀 7220

因為對條件變數不了解,只是看過。這次在外掛程式管理器中要實現外掛程式的載入和外掛程式的啟停的分離(原來時將外掛程式載入和啟動放到了一起,外掛程式載入後就直接啟動,然後從外掛程式對應的感測器中讀取資料、儲存)。現在要求在外掛程式管理器在自身程序中將外掛程式載入進來,每個外掛程式作為乙個單獨的執行緒,執行緒啟動之後,處於休眠狀態,這樣不消耗cpu資源。使用方的程式是乙個單獨的程序,它決定什麼時候啟動什麼外掛程式。

這個需求給我們帶來2個問題:(1)程序間怎麼通訊,因為原來外掛程式的管理都在外掛程式管理器這個程序中,外掛程式物件和外掛程式管理器物件都是已知的,或者說呼叫載入外掛程式和啟動外掛程式相關函式的物件是同乙個,現在要在外掛程式管理器物件中載入外掛程式,而在另外乙個程序中啟動外掛程式,那麼這兩個程序怎麼共用乙個外掛程式物件;(2)外掛程式的啟動停止需要訊號量或者條件變數來控制,原來並沒有接觸過多。

針對上述問題,對於程序間通訊,我們準備採用黑板的機制,來監聽使用者需要我們啟停哪個外掛程式,通過黑板傳遞要啟停的外掛程式的描述,比如外掛程式名稱(目前和我和煙台時通過storepath這個字串來唯一建立聯絡的,但是storepath和外掛程式名又在同乙個sensor類物件中),所以這一步是可以打通的,煙台接收使用者傳來的要啟停的外掛程式名,寫到黑板上;我這邊的callback接收外掛程式名,然後從map中找到對應的外掛程式物件的指標,然後呼叫外掛程式的notify_wake或者notify_wait()(這倆函式都要在sensorpluginbase和labelgeneratorbase中增加),實現對條件變數的啟用和休眠,從而實現執行緒的啟動和暫停。

#include #include #include #include #include #include #include //這個類似具體的外掛程式類

class testcond

void gendata();//執行緒函式

void notifywake();//啟用執行緒

void setwait();//掛起執行緒

~testcond() {}

};void testcond::gendata(/* args */)

//執行緒休眠

void testcond::setwait()

int main()

sleep(2);

test.setwait();

std::cout << "sencond wait" << std::endl;

sleep(2);

test.notifywake();

std::cout << "sencond wake" << std::endl;

std::cout << "process done.\n";

getchar();

sleep(50);

return 0;

}

wsw@wsw:~/test/c++/conditioncar/src$ ./cond 

1111

ready is 0

222wait done.

moti1111111111

count is 0

count is 1

count is 2

count is 3

count is 4

count is 5

count is 6

count is 7

count is 8

count is 9

count is 10

count is 11

count is 12

count is 13

count is 14

count is 15

count is 16

count is 17

count is 18

sencond wait

count is 19

222moti1111111111

sencond wake

process done.

count is 20

count is 21

count is 22

count is 23

count is 24

count is 25

count is 26

count is 27

count is 28

count is 29

count is 30

count is 31

count is 32

count is 33

count is 34

count is 35

count is 36

如果沒有while(!ready)則每次在while(1)中cv.wait(lck)都會執行,也就是每次都會等待,notify之後,才會繼續往後走。

#include #include #include #include #include #include #include //這個類似具體的外掛程式類

class testcond

void gendata();//執行緒函式

void notifywake();//啟用執行緒

void setwait();//掛起執行緒

~testcond() {}

};void testcond::gendata(/* args */)

//執行緒休眠

void testcond::setwait()

int main()

sleep(2);

test.setwait();

std::cout << "sencond wait" << std::endl;

sleep(2);

test.notifywake();

std::cout << "sencond wake" << std::endl;

std::cout << "process done.\n";

getchar();

sleep(50);

return 0;

}

wsw@wsw:~/test/c++/conditioncar/src$ ./cond

1111

ready is 0

222wait done.

moti1111111111

count is 0

222sencond wait

moti1111111111

sencond wake

process done.

count is 1

222

那我們猜測notify_one()是不是沒有用啊,下面我們注釋掉該函式的呼叫。

#include #include #include #include #include #include #include //這個類似具體的外掛程式類

class testcond

void gendata();//執行緒函式

void notifywake();//啟用執行緒

void setwait();//掛起執行緒

~testcond() {}};

void testcond::gendata(/* args */)

//執行緒休眠

void testcond::setwait()

int main()

sleep(2);

test.setwait();

std::cout << "sencond wait" << std::endl;

sleep(2);

test.notifywake();

std::cout << "sencond wake" << std::endl;

std::cout << "process done.\n";

getchar();

sleep(50);

return 0;

}

輸出如下:

ok@ok-ts:~$ ./a.out 

1111

ready is 0

222wait done.

moti1111111111

sencond wait

moti1111111111

sencond wake

process done.

count is 0也沒有列印出來,說明是真的卡在了cv.wait(lck)處,後面都不會執行。這也說明該執行緒沒有被啟用,cv.wait(lck)所在的while也不會執行,因為卡在了cv.wait處,根本不往下面執行。

我們進一步把while(!ready)也注釋掉,兩者輸出一致。

1111

ready is 0

222wait done.

moti1111111111

sencond wait

moti1111111111

sencond wake

process done.

這麼說來,notify_one還是有用的。

C C 使用訊號量控制線程執行順序

include include semaphore sem f r include 訊號量的主要函式有 函式名 sem init 功能 對指定訊號初始化 引數1 sem 訊號,引數2 pshared 0時,訊號在當前程序的多個執行緒之間共享 引數3 unsigned 引數4 value表示初始化訊號...

C 多執行緒中使用條件變數示例

換一下 std unique locklck mtx 加鎖的位置。發現在多個執行緒使用同乙個互斥鎖的時候,如果在while flag 之外加鎖,則某個獲取鎖的執行緒將會一次執行完畢,然後釋放鎖,供其他執行緒搶占。其他執行緒一旦持有鎖,也是直接完畢之後才釋放鎖。如果把鎖加到while flag 裡面,...

C 使用Semaphore(訊號量)控制多執行緒

在c net中,當需要動態控制線程的數量時,我們可以使用semaphore來控制最大執行緒數。class program thread sleep 1000 console writeline main方法結束 授予5個請求 semaphore release 5 console readline ...