基礎的生產者消費者模型,生產者向公共快取區寫入資料,消費者從公共快取區讀取資料進行處理,兩個執行緒訪問公共資源,加鎖實現資料的一致性。
通過加鎖來實現
1class
produce_1
8void
runproduce() 15}
16void
join()
20void
start()
23void
stop()
26private
:27 std::mutex *m_mt;
28 std::queue *m_que;
29volatile
bool
m_stop;
30 std::shared_ptrm_trd;
31};
3233
34/*
35*單緩衝乙個同步佇列 效率較低
36*/
37class
consume_1
4445
void
runconsume()
52 std::cout << "
consume_1 consume
"<54}
55void
join()
59void
start()
62void
stop()
65private
:66 std::mutex *m_mt;
67 std::queue *m_que;
68volatile
bool
m_stop;
69 std::shared_ptrm_trd;
70 };
通過條件變數來實現
1 typedef structmutex_conditionmutex_condition;56
class
produce
13void
join()
17void produce(int
enter)
2223
void
runproduce() 29}
3031
void
start()
34void
stop()
3738
private
:39 std::queue *m_que;
40 mutex_condition *m_mc;
41 std::shared_ptrm_trd;
42volatile
bool
m_stop;
43};
4445
46class
consume
53void
join()
57void
consume()
63 m_que->pop();
64 std::cout << "
consume thread consume
"<66void
runconsume() 71}
72void
start()
75void
stop()
7879
private
:80 std::queue *m_que;
81 mutex_condition *m_mc;
82 std::shared_ptrm_trd;
83volatile
bool
m_stop;
8485 };
二、生產者消費者-雙緩衝
乙個公共快取區,由於多執行緒訪問的鎖衝突較大,可以採取雙緩衝手段來解決鎖的衝突
雙緩衝的關鍵:雙緩衝佇列的資料交換
1)生產者執行緒不斷的向生產者佇列a寫入資料,當佇列中有資料時,進行資料的交換,交換開始啟動時通過條件變數通知交換執行緒來處理最先的資料交換。
2)資料交換完成後,通過條件變數通知消費者處理資料,此時交換執行緒阻塞到消費者資料處理完成時通知的條件變數上。
3)消費者收到資料交換後的通知後,進行資料的處理,資料處理完成後,通知交換執行緒進行下一輪的雙緩衝區的資料交換。
要點:
生產者除了在資料交換時,其餘時刻都在不停的生產資料。
資料交換佇列需要等待消費者處理資料完成的通知,以進行下一輪交換。
消費者處理資料時,不進行資料交換,生產者同時會不斷的生產資料,消費者需要等待資料交換完成的通知,並且傳送消費完成的通知給交換執行緒
使用條件變數的版本實現
1 typedef structmutex_conditionmutex_condition;56
class
produce_1
16void
runproduce()
2425}26
void
join()
30void
start()
33void
stop()
36private
:37 mutex_condition *m_read_mc;
38 mutex_condition *m_writer_mc;
39 std::queue *m_read_que;
40 std::queue *m_writer_que;
41volatile
bool
m_stop;
42 std::shared_ptrm_trd;
43};
4445
46class
consume_1
5657
void
runconsume()
64//
deal data
65//
std::lock_guardulg(m_read_mc->mt);
66while (!m_read_que->empty())
70 m_switch_mc->cv.notify_one();71}
72}73}
74void
join()
78void
start()
81void
stop()
84private
:85 mutex_condition *m_read_mc;
86 mutex_condition *m_writer_mc;
87 mutex_condition *m_switch_mc;
88 std::queue *m_read_que;
89 std::queue *m_writer_que;
90volatile
bool
m_stop;
91 std::shared_ptrm_trd;
92};
93void que_switch_trd(std::queue * read_que, std::queue * writer_que, mutex_condition * read_mc, mutex_condition * writer_mc,mutex_condition *switch_mc)
100 std::lock_guardulg_2(read_mc->mt);
101 std::swap(*read_que, *writer_que);
102 std::cout << "
switch queue
"<103if (!read_que->empty())
106}
107 std::unique_lockulg_2(switch_mc->mt);
108while (!read_que->empty())
111}
112}
113int
main()
使用互斥鎖的實現
1 #include2 #include3 #include4 #include5 #include67class
dbqueue
14void swap(std::queue &read_que)
19private
:20 std::queuem_write_que;
21std::mutex m_mt;
22};
23void produce(dbqueue *que) 28}
29void consume(dbqueue *que) 40}
41}42}
43int
main()
44
兩個版本的區別 sleep的區別,sleep處理的時效性較差,不加sleep,cpu佔用率又比較高,所以條件變數是比較好的選擇。
C 11實現簡單生產者消費者模式
當前c 11已經實現了多執行緒 互斥量 條件變數等非同步處理函式,並且提供了諸如sleep之類的時間函式,所以後面使用c 開發這一塊的時候完全可以實現跨平台,無需在windows下寫一套然後又在linux下寫一套了。本文用c 11實現了乙個簡單的生產者 消費者模式,生產者每1s將乙個數值放到雙向佇列...
c 11生產者消費者
綜合運用 c 11 中的新的基礎設施 主要是多執行緒 鎖 條件變數 來闡述乙個經典問題 生產者消費者模型,並給出完整的解決方案。include include include include include include static const int kitemrepositorysize 1...
c 11 多執行緒實現生產者消費者模型
include include include include include include using namespace std const int length 5 int buffer length int read index int write index mutex mtx cond...