目前遇到個奇怪的問題,有個主行程A,會不停的創建一些子執行緒,這些子執行緒會呼叫CreateProcess創建一個子行程,子行程進行一些操作后會創建一個文本檔案寫入內容,子執行緒WaitForSingleObject等待它創建的子行程結束,等待時間最長1分鐘,然后獲取子行程創建的文本,如果子行程在1分鐘沒有回傳,就會在子執行緒中呼叫TerminateProcess終止它,子行程的操作一定不會阻塞,理論上,即使主行程A結束了,它的子執行緒創建的那些子行程也會自行結束,但是現在的問題是,某個時刻呼叫了TerminateProcess結束主行程A,那些子行程就掛起了,問題不是必現,出現的幾率也不高,但見過幾次。難道TerminateProcess方式會導致子行程掛起?有沒有什么好辦法保證A行程被Kill后,所有的子行程也退出?
uj5u.com熱心網友回復:
《Windows編程啟示錄》19.6 為什么有些行程在被終止之后還停留在任務管理器中
當某個行程結束時(可能是正常結束,也可能是因為呼叫了像TerminateProcess之類的函式),這個行程的用戶態模塊將被洗掉。但內核態模塊只有在與執行緒相關的所有驅動程式執行完成之后才會被洗掉。
例如,如果某個執行緒正處于I/O操作中,那么將會給負責I/O的驅動程式發送一個內核信號來取消這個操作。
如果驅動程式的行為是良好的,那么它將清除與這個未完成I/O相關的一些資訊并且釋放執行緒。
如果驅動程式的行為是不好的(可能是因為驅動程式管理的硬體表現出奇怪的行為),那么可能需要花很長的時間來清除這個未完成的I/O。在這段時間里,驅動程式將不會釋放這個執行緒(以及這個執行緒所在的行程)。實際的情況要更復雜一些,但這里的簡單模型對于我們的討論已經足夠。
……
換句話說,如果你終止了某個行程后還能在任務管理器中看到這個行程,那么實際上這個行程已經停止運行了,只不過還有些殘留的資訊保留在系統中,只有當與這個行程相關的所有驅動程式都完成了清除操作并且指向這個行程的句柄都已經關閉,行程才會完全消失。
uj5u.com熱心網友回復:
子行程的操作一定不會阻塞,但它有時確實是超過了預想的 1分鐘的最大的執行時間;我覺得應該對這樣狀態的行程 attatch 進去看看,它這時處在什么問題,它是怎么用掉了 1分鐘的,能不能解決了。uj5u.com熱心網友回復:
我的現象不像是超時的問題,行程在串列中顯示的時間遠遠超過了1分鐘(觀察結果是過了一整夜還在),這個子行程有一個寫文本的操作,大概會寫50M的樣子,按照趙4老師的說法“如果驅動程式的行為是不好的(可能是因為驅動程式管理的硬體表現出奇怪的行為),那么可能需要花很長的時間來清除這個未完成的I/O。”,可能就是“驅動程式的行為是不好的”,先繼續觀察這個現象會不會復現。感謝zara和zhao4zhong1
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/102709.html
標籤:Windows客戶端使用
