C 多執行緒框架(三) 訊息佇列

2021-07-02 13:16:27 字數 2527 閱讀 8231

原帖: 

首先,之前,多執行緒一些基本的東西,包括執行緒建立,互斥鎖,訊號量,我們都已經封裝,下面來看看訊息佇列

我們盡量少用系統自帶的訊息佇列(比如linux的sys/msgqueue),那樣移植性不是很強,我們希望的訊息佇列,在訊息打包和提取都是用的標準的c++資料結構,當然,你也可以用鍊錶或者是fifo,那樣得先寫個鍊錶或者fifo出來。

我比較懶,直接用的c++的stl的deque,即雙埠佇列,這樣可靠性***,當然,速度可能沒有自己寫的鍊錶快,但是沒關係,使用雙埠佇列還可以根據你自己的需要將資料插入到佇列頭或者佇列尾,這樣在訊息有優先順序的情況下還是有用的。

訊息佇列的核心作用其實很簡單,乙個或多個執行緒往乙個佇列後面堆資料,另外的乙個執行緒從佇列前面取資料處理,基本操作也只有兩個,乙個發,乙個收,所以,我們定義訊息佇列基類為:

[cpp]view plain

copy

print?

class

cmsgqueue  

private

:  char

*msg_queue_name;  

};  

然後記得在coperratingsystemfactory裡加上建立訊息佇列的方法:

[cpp]view plain

copy

print?

class

coperatingsystemfactory  

;  

最後,從cmsgqueue繼承乙個clinuxmsgqueue,然後把recvmsg和sendmsg實現吧,實現的時候注意一下。

單純的操作雙埠fifo不行,我們希望是接收訊息的時候如果沒有訊息,執行緒阻塞在那裡等待訊息直到有訊息到來才接著執行,所以,接收訊息的時候我們用了訊號量,阻塞在訊號量那裡,傳送訊息的時候操作完佇列,傳送乙個訊號量出去。

其次,對於佇列的操作,我們希望是原子性的,不然乙個正在收乙個正在發就亂了,所以操作佇列的時候我們用互斥鎖來鎖一下,保證基本的原子性。

對應到具體的程式就是

1.為每個訊息佇列申請乙個鎖,乙個訊號量

[cpp]view plain

copy

print?

clinuxmsgqueue::clinuxmsgqueue(

const

char

*pname):  

cmsgqueue(pname)    

接收訊息的時候:

[cpp]view plain

copy

print?

bool

clinuxmsgqueue::recvmsg(unsigned 

int&m_msg_code,

void

*&p_msg)  

queue_element = m_queue.front();  

m_queue.pop_front();  

m_msg_code = queue_element.msg_code;  

p_msg = queue_element.p_message;  

//操作佇列結束

p_mutex->unlock(); //解除鎖定

return

true

;  }  

傳送的時候也是類似的方式進行,這樣,乙個最簡單訊息佇列就完成了。如果我們要使用訊息佇列的話,很簡單,在main.cpp中

[cpp]view plain

copy

print?

intmain()    

當要在mainloop中傳送訊息的時候,只需要呼叫

[cpp]view plain

copy

print?

p_msg_send->sendmsg(code, (

void

*)p_msg);   

//其中p_msg_send是b執行緒的區域性變數,實際指向的是之前新建的訊息佇列q

在a執行緒中需要接受訊息,呼叫方法也類似,具體可以之間看**。

寫在後面的話:

當然,這個**還非常不完整,整個**量也沒有多少行,在這裡,我只是提供乙個**框架的方法,作為乙個demo給大家參考,如果真的需要實際使用還有很多很多地方需要修改的,github上我的**也不能在生產軟體中實際使用,在實際的專案中,我也實現了乙個沒有任何第三方的執行緒庫,比這個複雜多了,還包括事件處理,等待超時,訊息廣播,訊息訂閱等模組,而且能執行在linux,ecos等多個平台上,基本做到平台無關了,但由於各種原因我也沒辦法將**都公布出來,這裡所說的這個框架只是專案中線程庫提取出來的非常少的一部分,同樣,也只是提供一種程式設計的設計思想,後面的東西希望大家各自有各自的發掘和完善,也許你看了以後,會提出更加強大和簡潔的框架。

另外,github上的**我會繼續完善,將其他模組陸續加上,如果大家感興趣也可以跟我一起來完善,我盡量不使用之前實現過的執行緒庫的**,避免不必要的麻煩。

java多執行緒 訊息佇列

1 定義乙個佇列快取池 private static list queuecache new linkedlist 2 定義佇列緩衝池最大訊息數,如果達到該值,那麼佇列檢入將等待檢出低於該值時繼續進行。private integer offermaxqueue 2000 3 定義檢出執行緒,如果佇列...

多執行緒14 模擬訊息佇列

1.模擬queue author alienware public class myqueue public void put object obj catch interruptedexception e list.add obj count.getandincrement count syste...

多執行緒安全無鎖訊息佇列

技術介紹 cas 原子操作 是有cpu提供的原子操作。mydeque 入隊操作 void enqueue t value 通過援助操作,更新tail cas tail,tail,tail next 出對操作 t dequeue t temvalue q value recycle q 空間 retu...