青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

牽著老婆滿街逛

嚴(yán)以律己,寬以待人. 三思而后行.
GMail/GTalk: yanglinbo#google.com;
MSN/Email: tx7do#yahoo.com.cn;
QQ: 3 0 3 3 9 6 9 2 0 .

VC實(shí)現(xiàn)線程池

??????這兩天在做關(guān)于網(wǎng)絡(luò)蜘蛛的程序,希望可以通過(guò)線程池來(lái)提高程序的性能,網(wǎng)上搜索了一下,看到這方面的東西還不少,跟大家分享一下!~有許多應(yīng)用程序創(chuàng)建的線程花費(fèi)了大量時(shí)間在睡眠狀態(tài)來(lái)等待事件的發(fā)生。還有一些線程進(jìn)入睡眠狀態(tài)后定期被喚醒以輪詢工作方式來(lái)改變或者更新狀態(tài)信息。線程池可以讓你更有效地使用線程,它為你的應(yīng)用程序提供一個(gè)由系統(tǒng)管理的工作者線程池。至少會(huì)有一個(gè)線程來(lái)監(jiān)聽放到線程池的所有等待操作,當(dāng)?shù)却僮魍瓿珊螅€程池中將會(huì)有一個(gè)工作者線程來(lái)執(zhí)行相應(yīng)的回調(diào)函數(shù)。
? 你也可以把沒(méi)有等待操作的工作項(xiàng)目放到線程池中,用QueueUserWorkItem函數(shù)來(lái)完成這個(gè)工作,把要執(zhí)行的工作項(xiàng)目函數(shù)通過(guò)一個(gè)參數(shù)傳遞給線程池。工作項(xiàng)目被放到線程池中后,就不能再取消了。
? Timer-queue timers和Registered wait operations也使用線程池來(lái)實(shí)現(xiàn)。他們的回調(diào)函數(shù)也放在線程池中。你也可以用BindIOCompletionCallback函數(shù)來(lái)投遞一個(gè)異步IO操作,在IO完成端口上,回調(diào)函數(shù)也是由線程池線程來(lái)執(zhí)行。
? 當(dāng)?shù)谝淮握{(diào)用QueueUserWorkItem函數(shù)或者BindIOCompletionCallback函數(shù)的時(shí)候,線程池被自動(dòng)創(chuàng)建,或者Timer-queue timers或者Registered wait operations放入回調(diào)函數(shù)的時(shí)候,線程池也可以被創(chuàng)建。線程池可以創(chuàng)建的線程數(shù)量不限,僅受限于可用的內(nèi)存,每一個(gè)線程使用默認(rèn)的初始堆棧大小,運(yùn)行在默認(rèn)的優(yōu)先級(jí)上。
? 線程池中有兩種類型的線程:IO線程和非IO線程。IO線程等待在可告警狀態(tài),工作項(xiàng)目作為APC放到IO線程中。如果你的工作項(xiàng)目需要線程執(zhí)行在可警告狀態(tài),你應(yīng)該將它放到IO線程。
? 非IO工作者線程等待在IO完成端口上,使用非IO線程比IO線程效率更高,也就是說(shuō),只要有可能的話,盡量使用非IO線程。IO線程和非IO線程在異步IO操作沒(méi)有完成之前都不會(huì)退出。然而,不要在非IO線程中發(fā)出需要很長(zhǎng)時(shí)間才能完成的異步IO請(qǐng)求。
? 正確使用線程池的方法是,工作項(xiàng)目函數(shù)以及它將會(huì)調(diào)用到的所有函數(shù)都必須是線程池安全的。安全的函數(shù)不應(yīng)該假設(shè)線程是一次性線程的或者是永久線程。一般來(lái)說(shuō),應(yīng)該避免使用線程本地存儲(chǔ)和發(fā)出需要永久線程的異步IO調(diào)用,比如說(shuō)RegNotifyChangeKeyValue函數(shù)。如果需要在永久線程中執(zhí)行這樣的函數(shù)的話,可以給QueueUserWorkItem傳遞一個(gè)選項(xiàng)WT_EXECUTEINPERSISTENTTHREAD。
? 注意,線程池不能兼容COM的單線程套間(STA)模型。
?
? ????為了更深入地講解操作系統(tǒng)實(shí)現(xiàn)的線程池的優(yōu)越性,我們首先嘗試著自己實(shí)現(xiàn)一個(gè)簡(jiǎn)單的線程池模型。
?
? ????代碼如下:
??/************************************************************************/
??
/*?Test?Our?own?thread?pool.????????????????????????????????????????????*/
??
/************************************************************************/
??
??typedef?
struct?_THREAD_POOL
??
{
??????HANDLE?QuitEvent;
??????HANDLE?WorkItemSemaphore;
??
??????LONG?WorkItemCount;
??????LIST_ENTRY?WorkItemHeader;
??????CRITICAL_SECTION?WorkItemLock;
??
??????LONG?ThreadNum;
??????HANDLE?
*ThreadsArray;
??
??}
THREAD_POOL,?*PTHREAD_POOL;
??
??typedef?VOID?(
*WORK_ITEM_PROC)(PVOID?Param);
??
??typedef?
struct?_WORK_ITEM
??
{
??????LIST_ENTRY?List;
??
??????WORK_ITEM_PROC?UserProc;
??????PVOID?UserParam;
??????
??}
WORK_ITEM,?*PWORK_ITEM;
??
??
??DWORD?WINAPI?WorkerThread(PVOID?pParam)
??
{
??????PTHREAD_POOL?pThreadPool?
=?(PTHREAD_POOL)pParam;
??????HANDLE?Events[
2];
??????
??????Events[
0]?=?pThreadPool->QuitEvent;
??????Events[
1]?=?pThreadPool->WorkItemSemaphore;
??
??????
for(;;)
??????
{
??????????DWORD?dwRet?
=?WaitForMultipleObjects(2,?Events,?FALSE,?INFINITE);
??
??????????
if(dwRet?==?WAIT_OBJECT_0)
??????????????
break;
??
??????????
//
??????????
//?execute?user's?proc.
??????????
//
??
??????????
else?if(dwRet?==?WAIT_OBJECT_0?+1)
??????????
{
??????????????PWORK_ITEM?pWorkItem;
??????????????PLIST_ENTRY?pList;
??
??????????????EnterCriticalSection(
&pThreadPool->WorkItemLock);
??????????????_ASSERT(
!IsListEmpty(&pThreadPool->WorkItemHeader));
??????????????pList?
=?RemoveHeadList(&pThreadPool->WorkItemHeader);
??????????????LeaveCriticalSection(
&pThreadPool->WorkItemLock);
??
??????????????pWorkItem?
=?CONTAINING_RECORD(pList,?WORK_ITEM,?List);
??????????????pWorkItem
->UserProc(pWorkItem->UserParam);
??
??????????????InterlockedDecrement(
&pThreadPool->WorkItemCount);
??????????????free(pWorkItem);
??????????}

??
??????????
else
??????????
{
??????????????_ASSERT(
0);
??????????????
break;
??????????}

??????}

??
??????
return?0;
??}

??
??BOOL?InitializeThreadPool(PTHREAD_POOL?pThreadPool,?LONG?ThreadNum)
??
{
??????pThreadPool
->QuitEvent?=?CreateEvent(NULL,?TRUE,?FALSE,?NULL);
??????pThreadPool
->WorkItemSemaphore?=?CreateSemaphore(NULL,?0,?0x7FFFFFFF,?NULL);
??????pThreadPool
->WorkItemCount?=?0;
??????InitializeListHead(
&pThreadPool->WorkItemHeader);
??????InitializeCriticalSection(
&pThreadPool->WorkItemLock);
??????pThreadPool
->ThreadNum?=?ThreadNum;
??????pThreadPool
->ThreadsArray?=?(HANDLE*)malloc(sizeof(HANDLE)?*?ThreadNum);
??
??????
for(int?i=0;?i<ThreadNum;?i++)
??????
{
??????????pThreadPool
->ThreadsArray[i]?=?CreateThread(NULL,?0,?WorkerThread,?pThreadPool,?0,?NULL);
??????}

??
??????
return?TRUE;
??}

??
??VOID?DestroyThreadPool(PTHREAD_POOL?pThreadPool)
??
{
??????SetEvent(pThreadPool
->QuitEvent);
??
??????
for(int?i=0;?i<pThreadPool->ThreadNum;?i++)
??????
{
??????????WaitForSingleObject(pThreadPool
->ThreadsArray[i],?INFINITE);
??????????CloseHandle(pThreadPool
->ThreadsArray[i]);
??????}

??
??????free(pThreadPool
->ThreadsArray);
??
??????CloseHandle(pThreadPool
->QuitEvent);
??????CloseHandle(pThreadPool
->WorkItemSemaphore);
??????DeleteCriticalSection(
&pThreadPool->WorkItemLock);
??
??????
while(!IsListEmpty(&pThreadPool->WorkItemHeader))
??????
{
??????????PWORK_ITEM?pWorkItem;
??????????PLIST_ENTRY?pList;
??????????
??????????pList?
=?RemoveHeadList(&pThreadPool->WorkItemHeader);
??????????pWorkItem?
=?CONTAINING_RECORD(pList,?WORK_ITEM,?List);
??????????
??????????free(pWorkItem);
??????}

??}

??
??BOOL?PostWorkItem(PTHREAD_POOL?pThreadPool,?WORK_ITEM_PROC?UserProc,?PVOID?UserParam)
??
{
??????PWORK_ITEM?pWorkItem?
=?(PWORK_ITEM)malloc(sizeof(WORK_ITEM));
??????
if(pWorkItem?==?NULL)
??????????
return?FALSE;
??
??????pWorkItem
->UserProc?=?UserProc;
??????pWorkItem
->UserParam?=?UserParam;
??
??????EnterCriticalSection(
&pThreadPool->WorkItemLock);
??????InsertTailList(
&pThreadPool->WorkItemHeader,?&pWorkItem->List);
??????LeaveCriticalSection(
&pThreadPool->WorkItemLock);
??
??????InterlockedIncrement(
&pThreadPool->WorkItemCount);
???????ReleaseSemaphore(pThreadPool
->WorkItemSemaphore,?1,?NULL);
??
??????
return?TRUE;
??}

??
??VOID?UserProc1(PVOID?dwParam)
??
{
??????WorkItem(dwParam);
??}

??
??
void?TestSimpleThreadPool(BOOL?bWaitMode,?LONG?ThreadNum)
??
{
??????THREAD_POOL?ThreadPool;????
??????InitializeThreadPool(
&ThreadPool,?ThreadNum);
??????
??????CompleteEvent?
=?CreateEvent(NULL,?FALSE,?FALSE,?NULL);
??????BeginTime?
=?GetTickCount();
??????ItemCount?
=?20;
??
??????
for(int?i=0;?i<20;?i++)
??????
{
??????????PostWorkItem(
&ThreadPool,?UserProc1,?(PVOID)bWaitMode);
??????}

??????
??????WaitForSingleObject(CompleteEvent,?INFINITE);
??????CloseHandle(CompleteEvent);
??
??????DestroyThreadPool(
&ThreadPool);
??}

??????我們把工作項(xiàng)目放到一個(gè)隊(duì)列中,用一個(gè)信號(hào)量通知線程池,線程池中任意一個(gè)線程取出工作項(xiàng)目來(lái)執(zhí)行,執(zhí)行完畢之后,線程返回線程池,繼續(xù)等待新的工作項(xiàng)目。
??????線程池中線程的數(shù)量是固定的,預(yù)先創(chuàng)建好的,永久的線程,直到銷毀線程池的時(shí)候,這些線程才會(huì)被銷毀。
??????線程池中線程獲得工作項(xiàng)目的機(jī)會(huì)是均等的,隨機(jī)的,并沒(méi)有特別的方式保證哪一個(gè)線程具有特殊的優(yōu)先獲得工作項(xiàng)目的機(jī)會(huì)。
??????而且,同一時(shí)刻可以并發(fā)運(yùn)行的線程數(shù)目沒(méi)有任何限定。事實(shí)上,在我們的執(zhí)行計(jì)算任務(wù)的演示代碼中,所有的線程都并發(fā)執(zhí)行。
??????下面,我們?cè)賮?lái)看一下,完成同樣的任務(wù),系統(tǒng)提供的線程池是如何運(yùn)作的。
??
??
/************************************************************************/
??
/*?QueueWorkItem?Test.??????????????????????????????????????????????????*/
??
/************************************************************************/
??
??DWORD?BeginTime;
??LONG??ItemCount;
??HANDLE?CompleteEvent;
??
??
int?compute()
??
{
??????srand(BeginTime);
??
??????
for(int?i=0;?i<20?*1000?*?1000;?i++)
??????????rand();
??
??????
return?rand();
??}

??
??DWORD?WINAPI?WorkItem(LPVOID?lpParameter)
??
{
??????BOOL?bWaitMode?
=?(BOOL)lpParameter;
??
??????
if(bWaitMode)
??????????Sleep(
1000);
??????
else
??????????compute();
??
??????
if(InterlockedDecrement(&ItemCount)?==?0)
??????
{
??????????printf(
"Time?total?%d?second.\n",?GetTickCount()?-?BeginTime);
??????????SetEvent(CompleteEvent);
??????}

??
??????
return?0;
??}

??
??
void?TestWorkItem(BOOL?bWaitMode,?DWORD?Flag)
??
{
??????CompleteEvent?
=?CreateEvent(NULL,?FALSE,?FALSE,?NULL);
??????BeginTime?
=?GetTickCount();
??????ItemCount?
=?20;
??????
??????
for(int?i=0;?i<20;?i++)
??????
{
??????????QueueUserWorkItem(WorkItem,?(PVOID)bWaitMode,?Flag);
??????}
????
??
??????WaitForSingleObject(CompleteEvent,?INFINITE);
??????CloseHandle(CompleteEvent);
??}
????? 很簡(jiǎn)單,是吧?我們僅需要關(guān)注于我們的回調(diào)函數(shù)即可。但是與我們的簡(jiǎn)單模擬來(lái)比,系統(tǒng)提供的線程池有著更多的優(yōu)點(diǎn)。
????? 首先,線程池中線程的數(shù)目是動(dòng)態(tài)調(diào)整的,其次,線程池利用IO完成端口的特性,它可以限制并發(fā)運(yùn)行的線程數(shù)目,默認(rèn)情況下,將會(huì)限制為CPU的數(shù)目,這可以減少線程切換。它挑選最近執(zhí)行過(guò)的線程再次投入執(zhí)行,從而避免了不必要的線程切換。
????? 系統(tǒng)提供的線程池背后的策略,我們下一節(jié)繼續(xù)再談。
?
? 參考書目
?
? 1,??? MSDN Library
? 2,??? 《Windows高級(jí)編程指南》
? 3,??? 《Windows核心編程》
? 4,??? 《Windows 2000 設(shè)備驅(qū)動(dòng)程序設(shè)計(jì)指南》

posted on 2006-04-14 20:56 楊粼波 閱讀(24457) 評(píng)論(10)  編輯 收藏 引用 所屬分類: 文章收藏

評(píng)論

# re: VC實(shí)現(xiàn)線程池 2007-05-08 11:31 artcpp

十分感謝!看后受益多多!!  回復(fù)  更多評(píng)論   

# re: VC實(shí)現(xiàn)線程池 2007-07-07 10:09 lbblscy

同上!  回復(fù)  更多評(píng)論   

# re: VC實(shí)現(xiàn)線程池 2008-05-09 09:47 asf

不錯(cuò),謝謝  回復(fù)  更多評(píng)論   

# re: VC實(shí)現(xiàn)線程池 2008-11-03 18:14 胖鼠鼠

謝謝,:)  回復(fù)  更多評(píng)論   

# re: VC實(shí)現(xiàn)線程池 2009-07-09 22:57 shuizhiyun

從頭到尾仔細(xì)看了一遍,沒(méi)有看太明白,待會(huì)兒再看一遍  回復(fù)  更多評(píng)論   

# re: VC實(shí)現(xiàn)線程池 2012-02-28 10:49 wzw200

很想 很想學(xué)習(xí) 怎么沒(méi)有注呢   回復(fù)  更多評(píng)論   

# re: VC實(shí)現(xiàn)線程池 2012-06-19 09:52 宇宙鋒

看了一遍沒(méi)完全明白,應(yīng)該有適當(dāng)?shù)淖⑨尩模?nbsp; 回復(fù)  更多評(píng)論   

# re: VC實(shí)現(xiàn)線程池 2012-07-29 11:12 Linex

額,我也覺(jué)得沒(méi)看明白,感覺(jué)講解的還是不夠透徹啊,或者咱水平低了點(diǎn)。。。  回復(fù)  更多評(píng)論   

# re: VC實(shí)現(xiàn)線程池 2013-02-27 14:55 pengshuangqi

這個(gè)人在裝B  回復(fù)  更多評(píng)論   

# re: VC實(shí)現(xiàn)線程池 2014-05-20 14:25 VC

寫得不錯(cuò),以簡(jiǎn)單的方式實(shí)現(xiàn)了基本的線程池  回復(fù)  更多評(píng)論   

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            亚洲一区二区三区在线播放| 国产精品女主播| 亚洲精品乱码久久久久久久久| 久久久国产精品亚洲一区| 午夜精品免费视频| 欧美一区二区三区在线观看视频| 小嫩嫩精品导航| 久久综合九色综合久99| 欧美国产先锋| 日韩视频中文字幕| 性8sex亚洲区入口| 久久综合九九| 亚洲欧洲在线一区| 一本一本大道香蕉久在线精品| 国产欧美一区二区三区在线老狼| 欧美一区二区三区视频在线| 久久岛国电影| 看片网站欧美日韩| 欧美色视频在线| 狠狠久久婷婷| 亚洲一级片在线观看| 久久久五月天| 一区二区三区日韩| 久久久999精品| 欧美性一区二区| 亚洲大片在线| 午夜久久久久久| 亚洲国产毛片完整版| 亚洲欧美日本国产有色| 美女国产一区| 国产午夜精品视频| 一区二区不卡在线视频 午夜欧美不卡在 | 一区二区三区色| 久久嫩草精品久久久精品一| 亚洲精品国产精品乱码不99按摩| 先锋亚洲精品| 欧美性一区二区| 亚洲乱码一区二区| 久久手机免费观看| 亚洲男女自偷自拍图片另类| 欧美韩国日本综合| 伊人成年综合电影网| 午夜精品一区二区三区电影天堂| 亚洲大黄网站| 久久久国产视频91| 国产精品一区=区| 亚洲午夜成aⅴ人片| 亚洲经典三级| 欧美1区视频| 亚洲国产导航| 免费日韩av| 欧美在线日韩精品| 国产亚洲二区| 久久狠狠亚洲综合| 欧美一级精品大片| 国产午夜亚洲精品不卡| 欧美一区二区女人| 亚洲综合精品四区| 国产精品任我爽爆在线播放| 亚洲免费视频网站| 一区二区三区欧美在线| 欧美私人啪啪vps| 亚洲亚洲精品三区日韩精品在线视频| 亚洲激情在线视频| 欧美日韩一区二区在线| 亚洲午夜电影网| 在线一区二区日韩| 国产伦精品一区二区三| 午夜在线成人av| 欧美日韩成人| 欧美高清视频一二三区| 在线看视频不卡| 欧美jjzz| 免费看精品久久片| 夜夜嗨av一区二区三区免费区| 亚洲精品视频在线播放| 国产精品v日韩精品| 欧美怡红院视频| 久久黄金**| 亚洲精品一线二线三线无人区| 亚洲第一黄色| 欧美午夜片在线观看| 久久激情视频免费观看| 久久青青草原一区二区| 日韩一级视频免费观看在线| 在线视频你懂得一区| 国产一区二区欧美日韩| 欧美电影免费观看| 欧美日韩一区二区三区四区在线观看| 午夜精品久久久久久| 久久精品99| 一本色道久久| 欧美在线影院| 一区二区三区国产在线| 亚洲欧美视频一区| 亚洲欧洲一区二区天堂久久 | 最新国产成人在线观看| 国产精品久久久亚洲一区| 久久中文精品| 欧美四级电影网站| 欧美aⅴ99久久黑人专区| 欧美日韩一区二区三区视频| 久久精品免费电影| 欧美日韩在线免费观看| 麻豆91精品91久久久的内涵| 欧美另类99xxxxx| 久久影音先锋| 欧美日韩一区在线观看| 欧美成人r级一区二区三区| 欧美午夜视频在线观看| 免费不卡欧美自拍视频| 国产九区一区在线| 亚洲精品一区二区在线观看| 在线观看视频日韩| 午夜精品久久久久久久99樱桃| 亚洲免费观看视频| 久久综合99re88久久爱| 久久精品欧美| 国产精品久久久一区二区三区| 欧美高清视频在线观看| 国内精品久久久| 新67194成人永久网站| 亚洲一区二区动漫| 欧美日韩国产专区| 亚洲欧洲精品一区二区三区不卡| 狠狠色丁香婷婷综合影院| 欧美一区二区黄色| 午夜精品一区二区三区在线视 | 国产综合第一页| 亚洲视频在线观看网站| 欧美日韩精品是欧美日韩精品| 久久综合九色欧美综合狠狠| 国产一区二区三区日韩欧美| 亚洲一区高清| 欧美国产亚洲精品久久久8v| 久久国产欧美精品| 国模精品一区二区三区| 性欧美18~19sex高清播放| 午夜一区二区三视频在线观看| 欧美色大人视频| aa级大片欧美三级| 国产精品99久久久久久久久久久久| 欧美高清视频| 亚洲伦理在线免费看| 中文精品视频| 欧美性一区二区| 亚洲免费在线电影| 久久婷婷国产麻豆91天堂| 黄色av成人| 免费日韩成人| 亚洲精品综合在线| 亚洲自拍啪啪| 韩国久久久久| 欧美精品黄色| 亚洲一区二区黄| 久久亚洲综合色一区二区三区| 国产一区二区三区四区在线观看| 久久久久久久国产| 亚洲韩国日本中文字幕| 中文高清一区| 国产精品永久免费视频| 欧美专区日韩专区| 亚洲福利视频在线| 亚洲性图久久| 国语自产在线不卡| 欧美高清在线视频| 亚洲男人的天堂在线| 欧美激情精品久久久久久| 一区二区国产精品| 韩国在线一区| 欧美日韩成人免费| 久久国产直播| 一本色道久久综合狠狠躁篇怎么玩| 亚洲午夜羞羞片| 亚洲电影免费在线| 国产欧美亚洲一区| 欧美日韩国产123| 久久久久久网站| 中文欧美在线视频| 欧美国产先锋| 久久久久久9| 亚洲一区二区三区免费在线观看| 国产一区二区精品丝袜| 欧美日韩第一页| 久久久国产成人精品| 亚洲一二三级电影| 亚洲精品一区二区三区在线观看| 久久久99免费视频| 亚洲图色在线| 亚洲欧洲日产国产网站| 国产日韩欧美精品一区| 欧美日韩国产综合视频在线观看| 久久久国产精彩视频美女艺术照福利| 一区二区三区视频观看| 亚洲国产一区在线观看| 蜜臀91精品一区二区三区| 久久国产福利国产秒拍| 亚洲欧美国产三级| 在线中文字幕不卡| 99re8这里有精品热视频免费|