執行緒的Alertable與User APC

2022-01-12 07:39:07 字數 1850 閱讀 8043

在使用插user apc注入dll時,經常面臨乙個問題,那就是執行緒必須是處於alertable模式才能注入成功。但一直對這個alertable的含義不甚清楚,今天總算是把這個梗消化了。

微軟對alertable與apc的執行關係有詳細的描述:

其中有一段是這樣說的:

也就是說,正常情況下,使用者模式的apc是不會打斷使用者態程式的執行流的。除非,執行緒是alertable——可喚醒的。

so, what is alertable?

想象乙個應用場景:

客戶端程式每隔5分鐘就和服務端進行一次通訊,實現「心跳」,最簡單的就是使用sleep(5*60*1000)。那麼這樣一來,這5分鐘內,執行緒就沉睡了,如果這個時候有比較緊急的網路io事件發生怎麼辦呢?執行緒還在沉睡中,因為5分鐘時間還未到,所以無法及時處理這些事件。如何解決這個問題呢?那就是使用sleepex替換sleep。這個函式比起sleep就多了乙個引數alertable,表示該執行緒是「可喚醒的」,就是說,執行緒雖然等待時間未到,但如果發生一些事件,執行緒也會及時去處理。這些事件就是:io完成例程需要執行或者執行緒有apc需要交付。

核心中線程資料結構kthread中的alertable成員就是表示該執行緒是不是可喚醒的。這個成員會在什麼時候被賦值呢?參見wrk有三個巨集會設定該值:

initializedelayexecution()

initializewaitsingle()

initializewaitmultiple()

這三個巨集分別被

sleepex()---->kedelayexecutionthread()

waitforsingleobject()---->kewaitforsingleobject()

waitformultipleobjects()---->kewaitformultipleobjects()

呼叫。當上述呼叫發生時,執行緒alertable被置為true。同時,還會通過巨集testforalertpending設定kthread的另外乙個成員:userapcpending,當alertable為true,並且user apc佇列不為空,那麼該值將被置為true。

當從核心模式返回時,dispatch_user_apc在交付使用者模式apc前會判斷這個標誌,如果為false,則不會交付user apc。

這也就是為什麼當執行緒為alertale的時候,插入的user apc才會得到執行。

還有乙個問題:在程序啟動時使用驅動進行apc注入dll的時候,並沒有去考慮這個userapcpending標記,那為什麼apc就一定能得到執行呢?

這是因為,在xp中,程序初始化重要工作ldrinitializethunk本身就是使用apc進行執行的,所以在pspuserthreadstartup中對userapcpending設定為了true,這樣保證了初始的時候user apc能成功交付。

即使在win7中,ldrinitializethunk不再使用apc進行派遣,ldrinitializethunk在執行完成後會使用nttestalert,同樣會設定userapcpending為true。從而在返回使用者模式時,user apc同樣能交付。

但每次交付使用者模式的時候,userapcpending會被重置,所以執行緒啟動之後就不再能保證插apc能得到執行了。除非使用前面說到的那些alertable為true的等待函式,再次設定了userapcpending。

python usb通訊 python的USB通訊

手頭有個用libusb win32驅動的usb裝置,idvendor 0x5345,idproduct 0x1234,就來測試下pyusb模組的應用,pyusb讓usb程式設計變得簡單和方便,支援libusb 0.1.x libusb win32採用此庫 libusb 1.x,and openusb...

Linux top裡面 CPU和us 的解釋

有的同學會把 cpu和us 搞暈,也就是下圖所示在top的時候檢視cpu的資訊。這時有的同學會問 這兩個cpu到底哪個是對的。其實都是對的,只是表達的意思不一樣。官方解釋如下 cpu s 34.0 us 使用者空間占用cpu百分比 cpu 上次更新到現在的cpu時間占用百分比 讀到這裡我也不是十分理...

Linux top裡面 CPU和us 的解釋

我們有時會把 cpu和us 搞暈,也就是下圖所示在top的時候檢視cpu的資訊。這時有人會問 這兩個cpu到底哪個是對的。其實都是對的,只是表達的意思不一樣。官方解釋如下 cpu s 34.0 us 使用者空間占用cpu百分比 cpu 上次更新到現在的cpu時間占用百分比 讀到這裡我也不是十分理解他...