簡體   English   中英

當進程結束時,Sleep()中間的線程會發生什么?

[英]When a process ends, what happens to a thread that is in the middle of Sleep()?

我正在使用一個開始和結束線程的類。 線程在構造函數中創建。 線程函數有一個循環,只要標志為TRUE就會繼續。 該標志是該類的靜態成員。 解構函數將標志設置為FALSE。 這樣,類的每個實例都有一個關聯的線程,該線程在實例的生命周期內運行。

我試圖繞過解構器運行時發生的事情,如果這是一個結束線程的好方法。 我對多線程沒有多少經驗。

這就是我認為發生的事情。 在解構器內部,標志將設置為FALSE。 我們假設Sleep()正在為無窮大運行。 該對象被銷毀,但該標志仍然存在於內存中,因為它是靜態的。 但是,整個過程即將結束,所以在某些時候,靜態標志將會消失。 國旗會在線程之前消失嗎? 如果線程被進程結束強制返回,那么線程是否會再關心該標志? 我不知道此時發生了什么。

我在Visual Studio 2010中使用Visual C ++。

在Windows上,線程的生命周期小於或等於其被調用的過程。 因此,一旦過程結束,線程也就這樣結束。

在該進程中的所有線程終止之前,將無法完成正常的進程關閉。 因此,在這種情況下將設置標志,主線程可以終止,但創建的后台線程將繼續運行。 最終,他們將看到標志的FALSE值,退出循環,完成並且過程關閉將完成。

請注意,當一些其他線程仍在使用該對象(而不是靜態標志)時運行析構函數將產生未定義的結果。

想一想當線程處於處理中間而不是檢查活動標志時會發生什么,相當渺茫的機會吧。

最好寫一個stop(bool wait)函數,所以如果析構函數被調用並需要自動清理,你可以設置標志為stop,並阻塞直到線程將另一個標志設置為“stopped”,或者只是加入使用pthread_join的線程(不推薦,見下文)。

此外,當您阻止正常終止時,您也可以設置超時,並在出現錯誤時強制終止線程(並為調試生成警報)。

這取決於'解構者'是否實際上運行。

如果你試圖“解構”你在某個'OnClose'事件處理程序中描述的對象,設置靜態標志將指示線程在它們檢查它時終止。 如果他們不這樣做,線程將繼續休眠,(或者仍然停留在阻塞的任何呼叫上,或者繼續運行代碼)。

如果您不采取進一步操作等待對象線程終止,主GUI線程將運行,銷毀其所有GUI對象等,並調用ExitProcess()。

一旦調用了ExitProcess(),操作系統將在釋放任何內存之前停止進程的所有線程,無論它們處於什么狀態,(如包含您的標志的內存)。

調用ExitProcess()的線程永遠不會有控制權返回給它。 屬於同一進程但未在另一個核心上運行的其他線程的狀態設置為永不再運行。 屬於同一進程並在另一個核心上運行的其他線程具有在硬件上運行的核心,以阻止線程。

國旗會在線程之前消失嗎?

不會。在釋放托管標志的內存之前,線程將被停止。

如果您不希望發生強制終止,則必須采取措施等待對象線程的實際終止。 您必須通過在OnClose處理程序中設置適當的CloseAction來延遲主GUI線程調用ExitProcess。 當所有對象線程都已終止且對象的析構函數已完成時,GUI線程應僅關閉/釋放自身。

如果我真的,真的,真的必須這樣做,寧願通過PostMessaging一個'WM_THREADGONE'Windows消息到主GUI線程,(作為實際終止自己之前的對象線程的最后一個動作),並倒計時消息處理程序中的'threadCount'為零,因此保持GUI線程可用於處理消息,直到所有對象線程都自行終止。 Hard-Wait機制(如Join())只是死鎖生成器,具有很大的關閉問題容量,不應該使用。

我通常嘗試通過設計我的應用來解決所有線程終止問題,以便突然的,不自覺的線程終止是一個可接受的操作,然后讓Exitprocess()將所有內容都吹走。 這並不總是可行的,但是如果你可以僥幸逃脫它,它就更安全了。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM