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

  免費(fèi)注冊 查看新帖 |

Chinaunix

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

多對多的生產(chǎn)者消費(fèi)者程序,大家?guī)兔纯?/a> [復(fù)制鏈接]

論壇徽章:
0
跳轉(zhuǎn)到指定樓層
1 [收藏(0)] [報(bào)告]
發(fā)表于 2009-11-13 20:44 |只看該作者 |倒序?yàn)g覽
用條件變量和鎖進(jìn)行線程控制,問題如注釋所寫。就是消費(fèi)者線程內(nèi)的那個(gè)usleep語句,為什么它那么重要
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>

//多個(gè)生產(chǎn)者多個(gè)消費(fèi)者

#define BUFFSIZ 100000
#define MAXTHREADS 10

struct
{
&nbsp;&nbsp;&nbsp;&nbsp;int value;
&nbsp;&nbsp;&nbsp;&nbsp;pthread_t tid;
} buf[BUFFSIZ];

struct
{
&nbsp;&nbsp;&nbsp;&nbsp;pthread_mutex_t mutex;
&nbsp;&nbsp;&nbsp;&nbsp;int index;//生產(chǎn)者使用,索引buf位置

} shared = { PTHREAD_MUTEX_INITIALIZER, 0};

struct
{
&nbsp;&nbsp;&nbsp;&nbsp;pthread_mutex_t mutex;
&nbsp;&nbsp;&nbsp;&nbsp;pthread_cond_t cond;
&nbsp;&nbsp;&nbsp;&nbsp;int ready;//在該索引及之前的元素可以消費(fèi)

&nbsp;&nbsp;&nbsp;&nbsp;int consume;//消費(fèi)者將要消費(fèi)的元素下標(biāo)

} nready = {PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER, -1, 0};

void *produce(void *arg)
{
&nbsp;&nbsp;&nbsp;&nbsp;for (;;)
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pthread_mutex_lock(&shared.mutex);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (shared.index > BUFFSIZ - 1)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pthread_mutex_unlock(&shared.mutex);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return NULL;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;buf[shared.index].value = shared.index;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;buf[shared.index].tid = pthread_self();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;++shared.index;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pthread_mutex_unlock(&shared.mutex);

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pthread_mutex_lock(&nready.mutex);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;++nready.ready;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ( nready.ready >= nready.consume)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pthread_cond_broadcast(&nready.cond);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pthread_mutex_unlock(&nready.mutex);

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;++(*(int *)arg);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;usleep(1);
&nbsp;&nbsp;&nbsp;&nbsp;}
}

void *consume(void *arg)
{
&nbsp;&nbsp;&nbsp;&nbsp;int i;
&nbsp;&nbsp;&nbsp;&nbsp;for (;;)
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pthread_mutex_lock(&nready.mutex);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ( nready.consume>= BUFFSIZ)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pthread_mutex_unlock(&nready.mutex);
&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("consume thread %lu is donen", pthread_self());&nbsp;&nbsp;&nbsp;&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return NULL;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while ( nready.ready < nready.consume)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pthread_cond_wait(&nready.cond, &nready.mutex);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ( buf[nready.consume].value != nready.consume)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("error: buf[%d]=%d, tid = %lun", nready.consume, buf[nready.consume].value, buf[nready.consume].tid);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;++nready.consume;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pthread_mutex_unlock(&nready.mutex);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;usleep(1);// 如果沒有這句,多個(gè)消費(fèi)者就會死鎖。


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;++(*(int *)arg);
&nbsp;&nbsp;&nbsp;&nbsp;}
}


int main(int argc, char *argv[])
{
&nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;&nbsp;&nbsp;&nbsp;i, nprod, ncons ;
&nbsp;&nbsp;&nbsp;&nbsp;pthread_t&nbsp;&nbsp;&nbsp;&nbsp;tid_produce[MAXTHREADS], tid_consume[MAXTHREADS];
&nbsp;&nbsp;&nbsp;&nbsp;int pcount[MAXTHREADS] = {0};
&nbsp;&nbsp;&nbsp;&nbsp;int ccount[MAXTHREADS] = {0};

&nbsp;&nbsp;&nbsp;&nbsp;if (argc != 3)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;perror("usage: a.out <#producer線程數(shù)> <#consumer線程數(shù)>"), exit(1);
&nbsp;&nbsp;&nbsp;&nbsp;nprod = atoi(argv[1])> MAXTHREADS ? MAXTHREADS : atoi(argv[1]);
&nbsp;&nbsp;&nbsp;&nbsp;ncons = atoi(argv[2])> MAXTHREADS ? MAXTHREADS : atoi(argv[2]);

&nbsp;&nbsp;&nbsp;&nbsp;pthread_setconcurrency(nprod+ncons);
&nbsp;&nbsp;&nbsp;&nbsp;for (i = 0; i < nprod; i++)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pthread_create(&tid_produce[i], NULL, produce, &pcount[i]);
&nbsp;&nbsp;&nbsp;&nbsp;for (i = 0; i < ncons; i++)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pthread_create(&tid_consume[i], NULL, consume, &ccount[i]);

&nbsp;&nbsp;&nbsp;&nbsp;for (i = 0; i < nprod; i++)
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pthread_join(tid_produce[i], NULL);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("produce thread %lu is donen", tid_produce[i]);&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;for (i = 0; i < ncons; i++)
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pthread_join(tid_consume[i], NULL);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("consume thread %lu is donen", tid_consume[i]);&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;for(i=0; i<nprod; ++i)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(" producer %d n", pcount[i]);&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;for(i=0; i<ncons; ++i)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(" consumer %d n", ccount[i]);&nbsp;&nbsp;&nbsp;&nbsp;

&nbsp;&nbsp;&nbsp;&nbsp;exit(0);
}

論壇徽章:
0
2 [報(bào)告]
發(fā)表于 2009-11-13 20:52 |只看該作者
chinaunix的代碼格式比較好看,顏色很鮮明

論壇徽章:
1
天蝎座
日期:2013-10-23 21:11:03
3 [報(bào)告]
發(fā)表于 2009-11-14 20:37 |只看該作者
見過類似情況
那是Python里面的,一次起多個(gè)線程會報(bào)錯(cuò)
得起了一個(gè)sleep一小會再起一個(gè)線程才行

等待答案……

論壇徽章:
0
4 [報(bào)告]
發(fā)表于 2009-12-01 09:13 |只看該作者

論壇徽章:
8
CU大牛徽章
日期:2013-04-17 10:59:39CU大;照
日期:2013-04-17 11:01:45CU大;照
日期:2013-04-17 11:02:15CU大;照
日期:2013-04-17 11:02:36CU大;照
日期:2013-04-17 11:02:58技術(shù)圖書徽章
日期:2013-12-04 10:48:50酉雞
日期:2014-01-03 10:32:30辰龍
日期:2014-03-06 15:04:07
5 [報(bào)告]
發(fā)表于 2009-12-01 10:21 |只看該作者
不是死鎖,是死循環(huán)。


假如線程1持有鎖,并且在解鎖后立刻重新上鎖;那么在解鎖和上鎖中間,必須有線程切換,否則其他線程幾乎永遠(yuǎn)拿不到鎖。


因?yàn)榫程1持有鎖時(shí),其他線程將因?yàn)榈却龡l件不滿足而被操作系統(tǒng)放入等待隊(duì)列;那么線程1釋放鎖,其他線程只是從等待狀態(tài)回到了就緒狀態(tài);除非線程1時(shí)間片到,否則操作系統(tǒng)不會重新分配CPU時(shí)間片,其他線程也就不會得到執(zhí)行時(shí)間。

而在線程1中,從ulock到下一次lock,中間僅僅幾十甚至幾個(gè)機(jī)器指令那么一點(diǎn)點(diǎn)時(shí)間。如果在這么幾個(gè)機(jī)器指令執(zhí)行時(shí)間里,線程1沒有因?yàn)闀r(shí)間片到而被掛起,那么它就會重新上鎖,于是就導(dǎo)致其他諸線程被重新放入等待隊(duì)列;于是到了時(shí)間片切換時(shí),因?yàn)槠渌程未就緒,線程1必將繼續(xù)得到時(shí)間片……


加入usleep,相當(dāng)于不持有鎖情況下的線程1主動讓出控制權(quán)(因?yàn)榈却〞r(shí)器信號而陷入休眠);于是就相當(dāng)于強(qiáng)制操作系統(tǒng)進(jìn)行下一輪優(yōu)先級評估和時(shí)間片分配,其他線程就有了執(zhí)行機(jī)會。

[ 本帖最后由 shan_ghost 于 2009-12-1 10:47 編輯 ]

論壇徽章:
0
6 [報(bào)告]
發(fā)表于 2009-12-01 14:25 |只看該作者

回復(fù) #5 shan_ghost 的帖子

在經(jīng)典的round_robin調(diào)度中,會存在這樣的問題。說白了,就是其他線程被“餓死”。
但是,目前,大多數(shù)的操作系統(tǒng)都有防餓死的功能,一個(gè)線程隨著其占用的CPU時(shí)間的增多,其優(yōu)先級會下降?倳心敲匆粋(gè)時(shí)刻,其在unlock后,會被比他優(yōu)先級更高的線程搶占。

論壇徽章:
8
CU大;照
日期:2013-04-17 10:59:39CU大;照
日期:2013-04-17 11:01:45CU大;照
日期:2013-04-17 11:02:15CU大牛徽章
日期:2013-04-17 11:02:36CU大;照
日期:2013-04-17 11:02:58技術(shù)圖書徽章
日期:2013-12-04 10:48:50酉雞
日期:2014-01-03 10:32:30辰龍
日期:2014-03-06 15:04:07
7 [報(bào)告]
發(fā)表于 2009-12-01 14:58 |只看該作者

回復(fù) #6 drowndog 的帖子

問題是要等到操作系統(tǒng)防餓死機(jī)制啟動、在線程1釋放鎖的時(shí)候立刻剝奪它的時(shí)間片,這個(gè)時(shí)間可就不是一般的長了。

我在某個(gè)項(xiàng)目里遇到過類似問題。一個(gè)網(wǎng)絡(luò)程序,用打印字符串的方式來檢查其他線程執(zhí)行情況。
加個(gè)usleep,字符串打印非常頻繁,好像刷屏一樣,CPU占用也變得極低;去掉usleep,平均每半分鐘左右才能打出一次字符串,CPU占用也彪升到90%以上。
當(dāng)然,這也和他們的主線程設(shè)計(jì)有關(guān),有事沒事都瞎掃描。

注意: 防餓死是用來防止情況劣化到完全不可收拾地步的,不是用來幫你彌補(bǔ)程序設(shè)計(jì)缺陷的。

[ 本帖最后由 shan_ghost 于 2009-12-1 15:00 編輯 ]
您需要登錄后才可以回帖 登錄 | 注冊

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

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP