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

牽著老婆滿街逛

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

VC實現線程池

??????這兩天在做關于網絡蜘蛛的程序,希望可以通過線程池來提高程序的性能,網上搜索了一下,看到這方面的東西還不少,跟大家分享一下!~有許多應用程序創建的線程花費了大量時間在睡眠狀態來等待事件的發生。還有一些線程進入睡眠狀態后定期被喚醒以輪詢工作方式來改變或者更新狀態信息。線程池可以讓你更有效地使用線程,它為你的應用程序提供一個由系統管理的工作者線程池。至少會有一個線程來監聽放到線程池的所有等待操作,當等待操作完成后,線程池中將會有一個工作者線程來執行相應的回調函數。
? 你也可以把沒有等待操作的工作項目放到線程池中,用QueueUserWorkItem函數來完成這個工作,把要執行的工作項目函數通過一個參數傳遞給線程池。工作項目被放到線程池中后,就不能再取消了。
? Timer-queue timers和Registered wait operations也使用線程池來實現。他們的回調函數也放在線程池中。你也可以用BindIOCompletionCallback函數來投遞一個異步IO操作,在IO完成端口上,回調函數也是由線程池線程來執行。
? 當第一次調用QueueUserWorkItem函數或者BindIOCompletionCallback函數的時候,線程池被自動創建,或者Timer-queue timers或者Registered wait operations放入回調函數的時候,線程池也可以被創建。線程池可以創建的線程數量不限,僅受限于可用的內存,每一個線程使用默認的初始堆棧大小,運行在默認的優先級上。
? 線程池中有兩種類型的線程:IO線程和非IO線程。IO線程等待在可告警狀態,工作項目作為APC放到IO線程中。如果你的工作項目需要線程執行在可警告狀態,你應該將它放到IO線程。
? 非IO工作者線程等待在IO完成端口上,使用非IO線程比IO線程效率更高,也就是說,只要有可能的話,盡量使用非IO線程。IO線程和非IO線程在異步IO操作沒有完成之前都不會退出。然而,不要在非IO線程中發出需要很長時間才能完成的異步IO請求。
? 正確使用線程池的方法是,工作項目函數以及它將會調用到的所有函數都必須是線程池安全的。安全的函數不應該假設線程是一次性線程的或者是永久線程。一般來說,應該避免使用線程本地存儲和發出需要永久線程的異步IO調用,比如說RegNotifyChangeKeyValue函數。如果需要在永久線程中執行這樣的函數的話,可以給QueueUserWorkItem傳遞一個選項WT_EXECUTEINPERSISTENTTHREAD。
? 注意,線程池不能兼容COM的單線程套間(STA)模型。
?
? ????為了更深入地講解操作系統實現的線程池的優越性,我們首先嘗試著自己實現一個簡單的線程池模型。
?
? ????代碼如下:
??/************************************************************************/
??
/*?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);
??}

??????我們把工作項目放到一個隊列中,用一個信號量通知線程池,線程池中任意一個線程取出工作項目來執行,執行完畢之后,線程返回線程池,繼續等待新的工作項目。
??????線程池中線程的數量是固定的,預先創建好的,永久的線程,直到銷毀線程池的時候,這些線程才會被銷毀。
??????線程池中線程獲得工作項目的機會是均等的,隨機的,并沒有特別的方式保證哪一個線程具有特殊的優先獲得工作項目的機會。
??????而且,同一時刻可以并發運行的線程數目沒有任何限定。事實上,在我們的執行計算任務的演示代碼中,所有的線程都并發執行。
??????下面,我們再來看一下,完成同樣的任務,系統提供的線程池是如何運作的。
??
??
/************************************************************************/
??
/*?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);
??}
????? 很簡單,是吧?我們僅需要關注于我們的回調函數即可。但是與我們的簡單模擬來比,系統提供的線程池有著更多的優點。
????? 首先,線程池中線程的數目是動態調整的,其次,線程池利用IO完成端口的特性,它可以限制并發運行的線程數目,默認情況下,將會限制為CPU的數目,這可以減少線程切換。它挑選最近執行過的線程再次投入執行,從而避免了不必要的線程切換。
????? 系統提供的線程池背后的策略,我們下一節繼續再談。
?
? 參考書目
?
? 1,??? MSDN Library
? 2,??? 《Windows高級編程指南》
? 3,??? 《Windows核心編程》
? 4,??? 《Windows 2000 設備驅動程序設計指南》

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

評論

# re: VC實現線程池 2007-05-08 11:31 artcpp

十分感謝!看后受益多多!!  回復  更多評論   

# re: VC實現線程池 2007-07-07 10:09 lbblscy

同上!  回復  更多評論   

# re: VC實現線程池 2008-05-09 09:47 asf

不錯,謝謝  回復  更多評論   

# re: VC實現線程池 2008-11-03 18:14 胖鼠鼠

謝謝,:)  回復  更多評論   

# re: VC實現線程池 2009-07-09 22:57 shuizhiyun

從頭到尾仔細看了一遍,沒有看太明白,待會兒再看一遍  回復  更多評論   

# re: VC實現線程池 2012-02-28 10:49 wzw200

很想 很想學習 怎么沒有注呢   回復  更多評論   

# re: VC實現線程池 2012-06-19 09:52 宇宙鋒

看了一遍沒完全明白,應該有適當的注釋的!  回復  更多評論   

# re: VC實現線程池 2012-07-29 11:12 Linex

額,我也覺得沒看明白,感覺講解的還是不夠透徹啊,或者咱水平低了點。。。  回復  更多評論   

# re: VC實現線程池 2013-02-27 14:55 pengshuangqi

這個人在裝B  回復  更多評論   

# re: VC實現線程池 2014-05-20 14:25 VC

寫得不錯,以簡單的方式實現了基本的線程池  回復  更多評論   

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            久久久午夜精品| 欧美刺激午夜性久久久久久久| 国产欧美一区二区精品忘忧草| 欧美日韩视频一区二区| 欧美日韩精品一区二区三区四区 | 亚洲一区二区伦理| 亚洲一区二区动漫| 欧美一级专区| 欧美gay视频激情| 亚洲精品一区二区三| 亚洲主播在线播放| 久久久久久久欧美精品| 欧美日本一道本| 国产精品欧美日韩| 亚洲国产精品一区二区第四页av| 亚洲人成在线观看一区二区| 亚洲一级二级在线| 免费成人黄色| 中文国产亚洲喷潮| 久久青草欧美一区二区三区| 欧美色道久久88综合亚洲精品| 国产视频在线一区二区| 亚洲精品欧洲精品| 久久九九精品| 99精品99久久久久久宅男| 欧美在线亚洲一区| 欧美日韩一区二区三区四区在线观看 | 亚洲精品偷拍| 久久激情视频久久| 欧美日韩精品三区| 狠狠久久亚洲欧美| 亚洲综合日韩中文字幕v在线| 葵司免费一区二区三区四区五区| 亚洲免费久久| 久热精品视频在线免费观看| 国产精品视频免费| 亚洲视频你懂的| 欧美国产日韩一区二区| 午夜免费在线观看精品视频| 欧美日韩在线视频一区二区| 亚洲国产一区二区视频| 久久天天躁夜夜躁狠狠躁2022| 一区二区三区国产精华| 欧美激情在线狂野欧美精品| 亚洲成色777777在线观看影院| 亚洲欧美中文日韩v在线观看| 亚洲激情中文1区| 久久男人资源视频| 国产一区二区三区四区在线观看 | 亚洲欧美日韩一区二区在线| 91久久精品国产91久久| 老司机午夜精品| 尹人成人综合网| 久色婷婷小香蕉久久| 久久精品首页| 在线观看精品| 欧美成人精品在线| 免费亚洲电影在线观看| 亚洲激情在线观看视频免费| 欧美高清你懂得| 欧美国产丝袜视频| 一本大道久久精品懂色aⅴ| 亚洲精品综合在线| 国产精品成人观看视频免费| 亚洲综合二区| 午夜精品久久久久久久蜜桃app| 国产精品视频最多的网站| 欧美亚洲一区二区三区| 欧美一区二区三区日韩| 在线激情影院一区| 亚洲欧洲日产国产综合网| 欧美日本免费一区二区三区| 亚洲一区二区免费在线| 午夜亚洲视频| 影音先锋成人资源站| 亚洲电影自拍| 国产精品国产三级国产专播品爱网| 亚洲综合大片69999| 午夜亚洲性色视频| 亚洲国产老妈| 亚洲高清在线播放| 亚洲黄色影片| 亚洲专区在线| 精品盗摄一区二区三区| 欧美黄色视屏| 国产精品亚洲不卡a| 老司机一区二区| 欧美不卡视频一区发布| 在线一区免费观看| 欧美一区=区| 亚洲精品永久免费| 亚洲天堂av在线免费| 精品成人一区二区三区| 99国产精品久久久久久久成人热| 国产精品一区二区视频| 欧美激情综合色| 国产精品一区视频网站| 国产精品伦子伦免费视频| 亚洲国产高清视频| 亚洲国产第一| 亚洲精品日韩在线| 国产日韩高清一区二区三区在线| 久久久欧美精品| 欧美精选一区| 久热爱精品视频线路一| 国产精品久久久久久久9999| 欧美 日韩 国产一区二区在线视频 | 一区在线视频观看| 一区二区三区视频在线看| 在线观看日韩av电影| 亚洲一区二区少妇| 亚洲九九精品| 美女网站在线免费欧美精品| 欧美一区二区三区日韩| 国产精品99久久久久久久vr| 亚洲电影免费观看高清| 欧美少妇一区| 国产精品一区二区久久| 欧美午夜在线一二页| 国产精品视频精品视频| 国产午夜亚洲精品理论片色戒| 欧美特黄一级大片| 国产伦精品一区二区三区高清版| 国产精品极品美女粉嫩高清在线| 国产精品大片| 国产一区二区三区在线观看网站| 国产揄拍国内精品对白| 在线观看国产成人av片| aaa亚洲精品一二三区| 久久精品国产99精品国产亚洲性色 | 欧美日韩精品二区第二页| 久久久午夜视频| 国产日韩精品一区二区三区 | 亚洲最新合集| 99精品国产一区二区青青牛奶| 久久琪琪电影院| 欧美成人亚洲成人| 亚洲国产你懂的| 美女主播一区| 亚洲人成人一区二区三区| 日韩一区二区高清| 欧美视频免费| 亚洲欧美韩国| 久久精品亚洲一区二区三区浴池| 欧美一区二区三区免费观看| 亚洲一区二区三区四区视频 | 日韩亚洲欧美一区二区三区| 亚洲高清av在线| 免费高清在线视频一区·| 欧美国产亚洲精品久久久8v| 亚洲成色www8888| 久久伊人免费视频| 亚洲国产成人精品视频| 中文精品视频| 国产精品午夜电影| 久久免费精品日本久久中文字幕| 欧美成va人片在线观看| 亚洲美女精品一区| 国产精品久久看| 久久久精品久久久久| 亚洲国产天堂久久国产91| 一区二区三区四区五区视频| 国产片一区二区| 在线午夜精品自拍| 亚洲人成绝费网站色www| 亚洲午夜精品网| 国产一区二区三区高清在线观看| 老司机免费视频一区二区| 99成人在线| 免费视频一区| 欧美三级电影一区| 久久精品卡一| 亚洲三级网站| 久久久一本精品99久久精品66| 亚洲三级影院| 国产视频亚洲| 欧美日本高清一区| 欧美一区二区三区在线免费观看| 亚洲国产导航| 久久成人免费日本黄色| 亚洲精选在线| 一区二区视频免费完整版观看| 欧美激情按摩| 亚洲国产精品一区二区第一页 | 日韩西西人体444www| 欧美亚洲三级| 亚洲精品色婷婷福利天堂| 国产欧美日韩亚洲一区二区三区| 快射av在线播放一区| 亚洲一区欧美| 亚洲精品偷拍| 欧美黄污视频| 久久综合色综合88| 亚洲欧洲99久久| av成人毛片| 亚洲毛片在线观看| 亚洲精品1区2区| 亚洲国产一二三| 亚洲国产黄色| 亚洲国产清纯|