亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費注冊 查看新帖 |

Chinaunix

  平臺 論壇 博客 文庫
最近訪問板塊 發(fā)新帖
查看: 2249 | 回復: 6
打印 上一主題 下一主題

[C] 關(guān)于生產(chǎn)者和消費者 [復制鏈接]

論壇徽章:
0
跳轉(zhuǎn)到指定樓層
1 [收藏(0)] [報告]
發(fā)表于 2015-10-20 17:34 |只看該作者 |倒序瀏覽
本帖最后由 Unix_C_Linux 于 2015-10-20 17:36 編輯

     情景:緩沖區(qū)放入1000數(shù), 生產(chǎn)者和消費者操作分別存取
         1.當生產(chǎn)者和消費者數(shù)量是1:1時,寫數(shù)據(jù)記錄和讀數(shù)據(jù)記錄相等,都是1000
         2.當生產(chǎn)者和消費者數(shù)量是1:N時,寫數(shù)據(jù)的數(shù)量是1000,為什么讀數(shù)據(jù)的數(shù)量之和大于1000?很多都是重復的,多個線程間是有鎖和條件變量的,為什么會讀出同樣的數(shù)據(jù)啊?

   代碼如下,編譯后可以直接運行。
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #define BUFFER_SIZE 16 // 緩沖區(qū)數(shù)量
  4. struct prodcons
  5. {
  6.         // 緩沖區(qū)相關(guān)數(shù)據(jù)結(jié)構(gòu)
  7.         int buffer[BUFFER_SIZE]; /* 實際數(shù)據(jù)存放的數(shù)組*/
  8.         pthread_mutex_t lock; /* 互斥體lock 用于對緩沖區(qū)的互斥操作 */
  9.         int readpos, writepos; /* 讀寫指針*/
  10.         pthread_cond_t notempty; /* 緩沖區(qū)非空的條件變量 */
  11.         pthread_cond_t notfull; /* 緩沖區(qū)未滿的條件變量 */
  12. };
  13. /* 初始化緩沖區(qū)結(jié)構(gòu) */
  14. void init(struct prodcons *b)
  15. {
  16.         pthread_mutex_init(&b->lock, NULL);
  17.         pthread_cond_init(&b->notempty, NULL);
  18.         pthread_cond_init(&b->notfull, NULL);
  19.         b->readpos = 0;
  20.         b->writepos = 0;
  21. }
  22. /* 將產(chǎn)品放入緩沖區(qū),這里是存入一個整數(shù)*/
  23. void put(struct prodcons *b, int data)
  24. {
  25.         pthread_mutex_lock(&b->lock);
  26.         /* 等待緩沖區(qū)未滿*/
  27.         if ((b->writepos + 1) % BUFFER_SIZE == b->readpos)
  28.         {
  29.                 pthread_cond_wait(&b->notfull, &b->lock);
  30.         }
  31.        
  32.         if(data != -1){
  33.                 printf("putdata\n");
  34.         }
  35.         /* 寫數(shù)據(jù),并移動指針 */
  36.         b->buffer[b->writepos] = data;
  37.         b->writepos = (b->writepos + 1)%BUFFER_SIZE;
  38.         /* 設置緩沖區(qū)非空的條件變量*/
  39.         pthread_cond_signal(&b->notempty);
  40.         pthread_mutex_unlock(&b->lock);
  41. }
  42. /* 從緩沖區(qū)中取出整數(shù)*/
  43. int get(struct prodcons *b)
  44. {
  45.         int data;
  46.         pthread_mutex_lock(&b->lock);
  47.         /* 等待緩沖區(qū)非空*/
  48.         if (b->writepos == b->readpos)
  49.         {
  50.                 pthread_cond_wait(&b->notempty, &b->lock);
  51.         }
  52.         /* 讀數(shù)據(jù),移動讀指針*/
  53.         data = b->buffer[b->readpos];
  54.         if(data != -1){
  55.                 printf("getdata\n", data);
  56.         }
  57.         b->readpos = (b->readpos + 1) % BUFFER_SIZE;
  58.         /* 設置緩沖區(qū)未滿的條件變量*/
  59.         pthread_cond_signal(&b->notfull);
  60.         pthread_mutex_unlock(&b->lock);
  61.         return data;
  62. }

  63. /* 測試:生產(chǎn)者線程將1 到10000 的整數(shù)送入緩沖區(qū),消費者線
  64.    程從緩沖區(qū)中獲取整數(shù),兩者都打印信息*/
  65. #define OVER ( - 1)
  66. struct prodcons buffer;
  67. void *producer(void *data)
  68. {
  69.         int n;
  70.         for (n = 0; n < 1000; n++)
  71.         {
  72.                 //printf("%d --->\n", n);
  73.                 put(&buffer, n);
  74.         }
  75.            put(&buffer, OVER);
  76.            put(&buffer, OVER);
  77.            put(&buffer, OVER);
  78.         return NULL;
  79. }

  80. void *consumer(void *data)
  81. {
  82.         int d;
  83.         while (1)
  84.         {
  85.                 d = get(&buffer);
  86.                 if (d == OVER)
  87.                         break;
  88.         //        printf("xxx|%d\n", d);
  89.         }
  90.         return NULL;
  91. }

  92. int main(void)
  93. {
  94.         pthread_t th_a, th_b, th_c, th_d;
  95.         void *retval;
  96.         init(&buffer);
  97.         /* 創(chuàng)建生產(chǎn)者和消費者線程*/
  98.         pthread_create(&th_a, NULL, producer, 0);
  99.         pthread_create(&th_b, NULL, consumer, 0);
  100.         pthread_create(&th_c, NULL, consumer, 0);
  101.         pthread_create(&th_d, NULL, consumer, 0);
  102.         /* 等待四個線程結(jié)束*/
  103.         pthread_join(th_a, &retval);
  104.         pthread_join(th_b, &retval);
  105.         pthread_join(th_c, &retval);
  106.         pthread_join(th_d, &retval);
  107.         return 0;
  108. }
復制代碼

論壇徽章:
4
2015年辭舊歲徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:56:11IT運維版塊每日發(fā)帖之星
日期:2016-08-11 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-08-15 06:20:00
2 [報告]
發(fā)表于 2015-10-20 18:14 |只看該作者
一個小問題,需要#include <pthread.h>
問題出在get之前沒有判斷隊列是否為空。修復后的代碼片段如下:
  1. 44 /* 從緩沖區(qū)中取出整數(shù)*/
  2. 45 int get(struct prodcons *b)
  3. 46 {      
  4. 47         int data;
  5. 48         pthread_mutex_lock(&b->lock);
  6. 49         /* 等待緩沖區(qū)非空*/
  7. 50         if (b->writepos == b->readpos)
  8. 51         {      
  9. 52                 pthread_cond_wait(&b->notempty, &b->lock);
  10. 53         }
  11. 54         
  12. 55         if (b->writepos != b->readpos) {
  13. 56             /* 讀數(shù)據(jù),移動讀指針*/
  14. 57             data = b->buffer[b->readpos];
  15. 58             if(data != -1) {
  16. 59                 printf("getdata: %d\n", data);
  17. 60             }
  18. 61             b->readpos = (b->readpos + 1) % BUFFER_SIZE;
  19. 62             /* 設置緩沖區(qū)未滿的條件變量*/
  20. 63             pthread_cond_signal(&b->notfull);
  21. 64         }
  22. 65         pthread_mutex_unlock(&b->lock);
  23. 66         return data;
  24. 67 }
復制代碼

論壇徽章:
15
射手座
日期:2014-11-29 19:22:4915-16賽季CBA聯(lián)賽之青島
日期:2017-11-17 13:20:09黑曼巴
日期:2017-07-13 19:13:4715-16賽季CBA聯(lián)賽之四川
日期:2017-02-07 21:08:572015年亞冠紀念徽章
日期:2015-11-06 12:31:58每日論壇發(fā)貼之星
日期:2015-08-04 06:20:00程序設計版塊每日發(fā)帖之星
日期:2015-08-04 06:20:00程序設計版塊每日發(fā)帖之星
日期:2015-07-12 22:20:002015亞冠之浦和紅鉆
日期:2015-07-08 10:10:132015亞冠之大阪鋼巴
日期:2015-06-29 11:21:122015亞冠之廣州恒大
日期:2015-05-22 21:55:412015年亞洲杯之伊朗
日期:2015-04-10 16:28:25
3 [報告]
發(fā)表于 2015-10-20 20:55 |只看該作者
Unix_C_Linux 發(fā)表于 2015-10-20 17:34
情景:緩沖區(qū)放入1000數(shù), 生產(chǎn)者和消費者操作分別存取
         1.當生產(chǎn)者和消費者數(shù)量是1:1時,寫數(shù)據(jù) ...

59,60行對調(diào)一下。

論壇徽章:
0
4 [報告]
發(fā)表于 2015-10-21 09:17 |只看該作者
回復 2# happy_fish100


我知道線程A pthread_cond_wait會解鎖互斥量后進入等待狀態(tài),解鎖后別的線程B可以進入。如果此時生產(chǎn)者放入數(shù)據(jù)通知了線程A,而B正好進入臨界區(qū),這時候數(shù)據(jù)重復取了,是這個原因嗎?

   

論壇徽章:
4
2015年辭舊歲徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:56:11IT運維版塊每日發(fā)帖之星
日期:2016-08-11 06:20:00IT運維版塊每日發(fā)帖之星
日期:2016-08-15 06:20:00
5 [報告]
發(fā)表于 2015-10-21 09:40 |只看該作者
本帖最后由 happy_fish100 于 2015-10-21 09:42 編輯

回復 4# Unix_C_Linux

是的,就是你說的這個原因。
所以消費隊列前需要重新判斷一下隊列是否為空,就可以解決隊列已被其他線程消費掉的問題。

論壇徽章:
0
6 [報告]
發(fā)表于 2015-10-21 13:13 |只看該作者
回復 5# happy_fish100


    3q

論壇徽章:
9
程序設計版塊每日發(fā)帖之星
日期:2015-10-18 06:20:00程序設計版塊每日發(fā)帖之星
日期:2015-11-01 06:20:00程序設計版塊每日發(fā)帖之星
日期:2015-11-02 06:20:00每日論壇發(fā)貼之星
日期:2015-11-02 06:20:00程序設計版塊每日發(fā)帖之星
日期:2015-11-03 06:20:00程序設計版塊每日發(fā)帖之星
日期:2015-11-04 06:20:00程序設計版塊每日發(fā)帖之星
日期:2015-11-06 06:20:00數(shù)據(jù)庫技術(shù)版塊每周發(fā)帖之星
日期:2015-12-02 15:02:47數(shù)據(jù)庫技術(shù)版塊每日發(fā)帖之星
日期:2015-12-08 06:20:00
7 [報告]
發(fā)表于 2015-10-23 11:33 |只看該作者
談高性能高并發(fā)  隊列的選擇:  優(yōu)先選擇"lock-free"無鎖隊列

在做抗DOS處理的代碼時, 存在2個線程之間, 必須要交換數(shù)據(jù)的問題,  其中一個線程是管理線程, 一個是acceptor線程.
對于此類問題, 傳統(tǒng)的方式就是: 生產(chǎn)者和消費者模式, 二者之間, 通過隊列QUEUE, 雙方都加鎖(mutex)處理隊列.

我的解決方案是采用  Boost 超高性能 無鎖隊列來實現(xiàn),  只用了三條代碼就解決了此問題.  
這個無鎖隊列模塊已經(jīng)開發(fā)出來多年,  但是國內(nèi)C++程序員應用不多.  
無鎖隊列的優(yōu)勢:
它將保證線程無限次調(diào)用這個方法都能夠在有限步內(nèi)完成,而不會因為其他線程被阻塞而導致本線程無法在有限步內(nèi)完成,即“無鎖”。
Boost保證在任何情況下所有并發(fā)中有一個操作能夠得到執(zhí)行, 不必考慮"多線進程的優(yōu)先級反轉(zhuǎn)等策略".

三行代碼 就可以非常簡潔高效率的解決一切鎖(mutex)帶來的問題, .

#include <boost/lockfree/spsc_queue.hpp>
boost::lockfree::spsc_queue<unsigned int, boost::lockfree::capacity<65536> >  closed_ip_queue;  
closed_ip_queue.push( int_ip );
closed_ip_queue.pop( int_closed_ip )
還要加上檢查返回值的代碼
您需要登錄后才可以回帖 登錄 | 注冊

本版積分規(guī)則 發(fā)表回復

  

北京盛拓優(yōu)訊信息技術(shù)有限公司. 版權(quán)所有 京ICP備16024965號-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報專區(qū)
中國互聯(lián)網(wǎng)協(xié)會會員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關(guān)心和支持過ChinaUnix的朋友們 轉(zhuǎn)載本站內(nèi)容請注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP