C 11 實現生產者消費者雙緩衝

2022-03-27 06:32:47 字數 4847 閱讀 7465

基礎的生產者消費者模型,生產者向公共快取區寫入資料,消費者從公共快取區讀取資料進行處理,兩個執行緒訪問公共資源,加鎖實現資料的一致性。

通過加鎖來實現

1

class

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 struct

mutex_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 struct

mutex_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 #include6

7class

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...