生產者消費者問題,是永遠的經典.
單純讓多個線程去競爭,占有資源然后處理,會讓系統的復雜度變得相當復雜,並且整個系統的並發也很難控制.為了讓系統簡單化,流暢化,引入消息隊列,而且這樣,系統更具有相當高的吞吐量.因為做的事情簡單而有效.
根據具體業務的不同,個人(認為)把消息隊列分為1:1模型,還有就是N:M模型的.
如果消費者的消費能力非常高.個人認為就應該使用1:1的隊列.這種隊列足夠簡單,可以進行各種優化,比如避免動態內存分配,鎖優化,使用lock-free等.這樣可以讓主循環的等待時間降到最低,使其可以專心致志進行各種邏輯處理.
有時,有些業務邏輯,不是很在乎時許,允許比較小的時間誤差,而且消費能力很強的化,也是可以使用1:1的隊列,不過生產者變成了n個,消費者還是一個.:-D 當然這種場景,不是非常多.
這邊給出一個lock free的message queue.
如果消費者的消費能力比較差,還有一些業務,比如金錢相關的,比如數據庫存檔相關的,而且這樣的系統,想要提高吞吐量,就只能使用N:M的模型.只不過這邊把lock-free換成了mutex,雖然mutex有可能會陷入到內核,不過只要臨界區足夠小,操作足夠輕量級,效率還是蠻高的.一般的系統,都不會在這邊有瓶頸.
這邊給出一個blocking queue的實現.
消費速度\時序 | 關心 | 不關心 |
消費速度慢 | blocking | blocking |
消費速度快 | 1:1 lock free N:M blcoking |
lock free |
其實很多業務,1:1的就足夠快了.
PS: 其實N:M的lock free queue也是可以實現的,不過需要用到cas. fecth and add使不能實現n個並發的.另外,cas實現消息隊列的復雜性相當高,收益也不是非常有效(在CPU核數較多的情況下),故放棄了實現多並發的lock free隊列.
另外不關心時序,不是意味着一點都不關心,而是允許有一定的誤差,比如10ms.
本來還想貼代碼,想想算了,代碼在github上開源了,可以自己去看實現.
https://github.com/egmkang/green_turtle/blob/master/green_turtle/blocking_queue.h
https://github.com/egmkang/green_turtle/blob/master/green_turtle/message_queue.h