APC异步过程调用
轉自:http://blog.sina.com.cn/s/blog_c2ef450f010192hx.html
APC?異步過程調用
?
記得第一次看見這個名詞的時候,覺得云里霧罩,然而上網看了下它的介紹,感覺說的都是沒頭沒腦的
然而今天,我再次接觸了它,我將自己對其的理解寫下,若有不對,歡迎指正(參照《windows核心編程?》第五版)????????????????狼影?--------- 2013、10、18
好啦,廢話少說,讓我們進入正題:
?
首先我們應該明白的是在創建線程的時候,這個所謂的APC就已經建立,并且與線程相關聯,并且這個APC是個隊列;
隊列中項的產生:
那么是誰往隊列里面添加內容呢,這個就要說到設備驅動程序了,現在是不是感覺不知所以然,聽我慢慢講來;?當一個線程發出一個I/O請求時(在這里我們講的是異步I/O請求哦),設備驅動程序接收它的請求,那么線程呢就執行自己剩下的工作(直到某一點,它實在是執行不去(因為在這點必須要得到請求的I/O結果)),那么設備驅動程序在執行完I/O請求后,他怎么讓線程直到他已經執行完I/O了呢?
那就是它會在APC隊列中添加一項,那么問題又來啦,它又怎么會知道往這個線程中的APC隊列中添加項呢,嘿嘿,這當然是線程告訴他的,在哪告訴的呢,當然是在發送I/O請求時告訴的,在這我也不賣官司啦,直接說啦,線程在請求I/O操作時用的是ReadFileEx()或者WriteFileEx()函數,這兩個函數在發送I/O請求的時候,就告訴設備驅動程序,說”嗨,哥們,你處理完我的請求后,就把通知發送到我的APC隊列中啊,哥等你”; (當然這個隊列項的內容就是那個完成函數的地址和在I/O請求時那個OVERLAPPED結構的地址(至于什么是完成函數和OVERLAPPED結構,我想就不用多說了把)),
這下我們知道了APC隊列中項的由來,那么接下來我們要了解的是項的處理:
在項添加到APC隊列中時,它不會被馬上處理,(線程在有其他任務處理的情況下不能被打斷為了對線程APC隊列中的項進行處理,線程必須將自己置為可提醒狀態)
那么什么是可提醒狀態,怎么才能設為可提醒狀態呢?
可提醒狀態在我感覺他就是為了處理APC中的項而出來的概念,因為在隊列中有項的情況下,線程會處理那些項,而當APC隊列中沒有項的時候,那么線程就會是掛起狀態;(在我看來,這里的可提醒應該是通知的意思,就是通知APC隊列中有項,讓它處理)??記住!當且僅當線程的APC隊列中一項都沒有的情況下線程才會掛起
至于怎么讓線程成為可提醒狀態,windows為我們提供了6個函數
SleepEx()
WaitForSingleObjectEx()
WaitForMultiObjectEx()
SignalObjectAndWait()
GetQueuedCOmpletionStatusEx()
MsgWaitForMultipleObjectEx()
前五個函數的參數中最后一個參數是個BOOl值,表示調用線程是不是應該將自己置為可提醒狀態
對于最后一個函數的最后一個參數我們應該使用MWMO_ALERTABLE標志來讓線程進入可提醒狀態
?
還有一點是,當線程在掛起狀態時,將其喚醒的方法可以是等待內核對象的觸發,或者也可以在APC隊列中出現一個項,當一個項出現的情況下,系統會喚醒我們的線程(通過回調函數)并清空隊列,然后函數會立即返回---線程不會再次進行睡眠狀態來等待內核對象被觸發
總結
- 上一篇: 操作系统内核
- 下一篇: Kafka 优化参数 unclean.