win32多執行緒程式設計學習筆記(第六章 下) 收藏
繼續。。。
上面的程式片段使用waitformultipleobjects函式來等待,會有兩個問題:
第一、
只能等待小於64個的物件,這是waitformultipleobjects函式本身所帶來的限制。
第二、
你必須不斷根據「哪乙個handle被激發」而計算如何處理。那個這個程式的結構可不是很清晰,以後維護可不方便
那麼書上在這裡提供了乙個非同步過程呼叫(apcs)的方法來解決這些問題
apcs的核心觀點是:
注意:運用apcs,必須使用readfileex()、writefileex ()
例子:void winapimyfunc(dword dwerrorcode,
//完成碼
dword dwnumberofbytestransfered,// 被傳遞的位元組數目
)
if (++ncompletioncount == max_requests)
setevent(ghevent);
}
int main()
// 等待所有操作完成
waitforsingleobjectex(ghevent, infinite, true );
closehandle(ghfile);
return exit_success;
}
int queuerequest(int nindex, dword dwlocation, dword dwamount)
以上的三個程式片段都是對
具體運用;對付一般的i/o操作應是可以了,如果你需要更高的效率,那麼你就需要書上提到的
i/o completion ports了。
i/o completion ports也許是最好的方法了(看看書p172-p173你是否會有這種感覺呢?);
但i/o completion ports
好像很難理解,我試著從自己理解的角度來寫寫心得(也許不對);
描述:
把i/o completion ports看作容器,那麼在這個容器中放置若干個執行緒(書上說最好是cpu個數*2+2),這些個執行緒
隨時隨地的將被啟用去服務i/o請求。
為什麼i/o completion ports會很有效率?我是這樣想的:首先容器中保持的執行緒可以隨時承擔服務i/o請求的任務,其主要特點是:
兩個執行緒在不同的時間可以服務同乙個i/o請求
;
第二:這些個執行緒的排程由系統選擇安排。系統總是在它認為最合適的時機去排程執行緒做最合適的事。書上還說了其它的一些有利於效率的工作,我就不再一一描述了。
下面我們來看一下運用i/o completion ports這是咱們最關心的:
在p179有乙個
操作概觀
:對著它,我來解釋書上i/o completion ports的例子。
//注意:一定要對著書,把下面用到的win32函式的每個引數的含義弄清楚,這很重要
//――――――產生乙個i/o completion port
①
//構造乙個i/o completion port
ghcompletionport
= createiocompletionport(
invalid_handle_value,
null,
//不使用任何port
0, 0
// 使用預設的執行緒數
);
//――――――讓它和乙個檔案handle產生關聯
②
//將socket關聯到
①產生的i/o completion port,那麼以後發生在這個socket
//上的任何i/o操作,都由此i/o completion port中的執行緒處理
createiocompletionport( (handle)newsocket,
//注意,這裡是socket;原因見書p184
ghcompletionport
, //指定的i/o completion port
(dword)
pkey
,//乙個指標,指向自定義的結構 0
// 使用預設的執行緒數
);/* pkey,用於記錄在newsocket上發生的操作,
在這裡指向乙個自定義的結構
,此結構中儲存從客戶端讀入的資料和寫回客戶的資料*/
//――――――產生一堆執行緒
③
createworkerthreads();
//――――――下面是④、⑤步
for (;;)
//沒有讀完
⑤
/*下面這一段我將書上的issueread(pcntx)拿掉了,替換它的是issueread(pcntx)函式的實現*/
//讀操作,引發i/o completion port的操作
bresult = readfile(
(handle)pcntx->sock,
//記取客戶端的socket
pcntx->inbuffer,
//將從客戶端的中讀取的字元寫入inbuffer
1,//每次讀取乙個字元
&numread,
&pcntx->ovin
//嘿!這傢伙在這沒啥用
);}
上面程式片段沒有列出「避免completion packets」的程式**。
當寫入操作完成時,i/o completion port將收到乙個packets以說明寫入操作成功與否;如果寫入操作的結果(成功或失敗)不是很重要,那麼我們肯定不希望在每次寫入操作後都接收這樣乙個packets(因為浪費時間),我要遮蔽它,可以向下面這樣:
//對hevent向下面這樣處理
overlap.hevent = createevent(…);
overlap.hevent = (handle)((dword)overlap.hevent | 0x1);
//那麼 「寫操作」使用這個經過處理的 overlap後,i/o completion port不會再發packets
writefile(….&overlap);
限於我的表達能力,有些地方只能生硬的
描述出來;這篇筆記的作用是幫助我下次再看的時候能夠很快的拿住重點,對你而言可能也沒什麼用,但我為什麼要寫出來呢?因為寫筆記(我也不知道這能不能算是筆記)能夠幫助我更好的理解書上的內容,這一點我深有體會。回頭再看一下書,發現書上把這些技術描述的非常清楚。用詞也很準確,寥寥數筆直取技術核心。所以建議大家把書反覆的看,你會突然開竅
j(嗯!我就是這樣突然開竅)。
《Win32多執行緒程式設計》學習筆記 (1)
最近開始看 win32 多執行緒程式設計 感覺受益匪淺,寫出來的目的有兩個 一是想看看自己理解的程度,能否總結出作者真正想表達的內容。2是與大家共享。好了,廢話就不說那麼多了!文章開始講述了作業系統的演化,作者從早期的 ms dos1.0 版本單任務系統到 2.x的可以允許常駐程式 tsr 但是 m...
win32多執行緒程式設計
使用3個執行緒完成6個任務,工作的執行是靠呼叫sleep 來模擬,時間長度是隨機給予的,只要乙個執行緒結束,就會有另乙個執行緒被產生。taskques.cpp 定義控制台應用程式的入口點。include stdafx.h include include include define win32 le...
Win32 多執行緒程式設計
程序和執行緒都是作業系統的概念 程序是應用程式的執行例項 每個程序是由私有的虛擬位址空間 資料和其它各種系統資源組成 程序在執行過程中建立的資源隨著程序的終止而被銷毀 所使用的系統資源在程序終止時被釋放或關閉 執行緒是程序內部的乙個執行單元 系統建立好程序後 實際上就啟動執行了該程序的主執行執行緒 ...