Windows終止執行緒的四種方法

2021-07-30 12:04:57 字數 2545 閱讀 6949

終止執行緒執行

若要終止執行緒的執行,可以使用下面的方法:

• 執行緒函式返回(最好使用這種方法)。

• 通過呼叫 exitthread 函式,執行緒將自行撤消(最好不要使用這種方法)。

• 同乙個程序或另乙個程序中的執行緒呼叫 terminatethread 函式(應該避免使用這種方法)。

• 包含執行緒的程序終止執行(應該避免使用這種方法)。

下面將介紹終止執行緒執行的方法,並且說明執行緒終止執行時會出現什麼情況。

1.執行緒函式返回

始終都應該將執行緒設計成這樣的形式,即當想要執行緒終止執行時,它們就能夠返回。這是確保所有執行緒資源被正確地清除的唯一辦法。

如果執行緒能夠返回,就可以確保下列事項的實現:

• 作業系統將正確地釋放執行緒堆疊使用的記憶體。

• 系統將遞減執行緒核心物件的使用計數。

2.使用 exitthread 函式

可以讓執行緒呼叫 exitthread 函式,以便強制執行緒終止執行:

void exitthread(dword dwexitcode);

該函式將終止執行緒的執行,並導致作業系統清除該執行緒使用的所有作業系統資源。但是,c++ 資源(如 c++ 類物件)將不被撤消。由於這個原因,最好從執行緒函式返回,而不是通過呼叫 exitthread 來返回。

當然,可以使用 exitthread 的 dwexitthread 引數告訴系統將執行緒的退出**設定為什麼。exitthread 函式並不返回任何值,因為執行緒已經終止執行,不能執行更多的**。

3.使用 terminatethread 函式

呼叫 terminatethread 函式也能夠終止執行緒的執行:

bool terminatethread(handle hthread, dword dwexitcode);

與 exitthread 不同,exitthread 總是撤消呼叫的執行緒,而 terminatethread 能夠撤消任何執行緒。hthread 引數用於標識被終止執行的執行緒的控制代碼。當執行緒終止執行時,它的退出**成為你作為 dwexitcode 引數傳遞的值。同時,執行緒的核心物件的使用計數也被遞減。

注意 terminatethread 函式是非同步執行的函式,也就是說,它告訴系統你想要執行緒終止執行,但是,當函式返回時,不能保證執行緒被撤消。如果需要確切地知道該執行緒已經終止執行,必須呼叫 waitforsingleobject 或者類似的函式,傳遞執行緒的控制代碼。

設計良好的應用程式從來不使用這個函式,因為被終止執行的執行緒收不到它被撤消的通知。執行緒不能正確地清除,並且不能防止自己被撤消。

注意 當使用返回或呼叫 exitthread 的方法撤消執行緒時,該執行緒的記憶體堆疊也被撤消。但是,如果使用 terminatethread,那麼在擁有執行緒的程序終止執行之前,系統不撤消該執行緒的堆疊。microsoft故意用這種方法來實現 terminatethread。如果其他仍然正在執行的執行緒要引用強制撤消的執行緒堆疊上的值,那麼其他的執行緒就會出現訪問違規的問題。如果將已經撤消的執行緒的堆疊留在記憶體中,那麼其他執行緒就可以繼續很好地執行。

此外,當執行緒終止執行時,dll 通常接收通知。如果使用 terminatethread 強迫執行緒終止,dll 就不接收通知,這能阻止適當的清除。

4.在程序終止執行時撤消執行緒

我們知道,程序函式 exitprocess 和 terminateprocess 也可以用來終止執行緒的執行。差別在於這些執行緒將會使終止執行的程序中的所有執行緒全部終止執行。另外,由於整個程序已經被關閉,程序使用的所有資源肯定已被清除。這當然包括所有執行緒的堆疊。這兩個函式會導致程序中的剩餘執行緒被強制撤消,就像從每個剩餘的執行緒呼叫 terminatethread 一樣。顯然,這意味著正確的應用程式清除沒有發生,即 c++ 物件撤消函式沒有被呼叫,資料沒有轉至磁碟等等。

執行緒終止執行時發生的操作

當執行緒終止執行時,會發生下列操作:

• 執行緒擁有的所有使用者物件均被釋放。在 windows 中,大多數物件是由包含建立這些物件的執行緒的程序擁有的。但是乙個執行緒擁有兩個使用者物件,即視窗和掛鉤。當執行緒終止執行時,系統會自動撤消任何視窗,並且解除安裝執行緒建立的或安裝的任何掛鉤。其他物件只有在擁有執行緒的程序終止執行時才被撤消。

• 執行緒的退出**從 still_active 改為傳遞給 exitthread 或 terminatethread 的**。

• 執行緒核心物件的狀態變為已通知。

• 如果執行緒是程序中最後乙個活動執行緒,系統也將程序視為已經終止執行。

• 執行緒核心物件的使用計數遞減 1。

當乙個執行緒終止執行時,在與它相關聯的執行緒核心物件的所有未結束的引用關閉之前,該核心物件不會自動被釋放。

一旦執行緒不再執行,系統中就沒有別的執行緒能夠處理該執行緒的控制代碼。然而別的執行緒可以呼叫 getexitcodethread 來檢查由 hthread 標識的執行緒是否已經終止執行。如果它已經終止執行,則確定它的退出**:

bool getexitcodethread(handle hthread, pdowrd pdwexitcode);

退出**的值在 pdwexitcode 指向的 dword 中返回。如果呼叫 getexitcodethread 時執行緒尚未終止執行,該函式就用 still_active 識別符號(定義為 0x103)填入 dword。如果該函式執行成功,便返回 true

Windows終止執行緒執行的四種方法

終止執行緒執行 若要終止執行緒的執行,可以使用下面的方法 執行緒函式返回 最好使用這種方法 通過呼叫 exitthread 函式,執行緒將自行撤消 最好不要使用這種方法 同乙個程序或另乙個程序中的執行緒呼叫 terminatethread 函式 應該避免使用這種方法 包含執行緒的程序終止執行 應該避...

Windows下的四種執行緒同步方法

critical section 臨界區 用來實現 排他性占有 適用範圍是單一程序 的各執行緒之間。它是 乙個區域性性物件,不是乙個核心物件。快速而有效率。不能夠同時有乙個以上的 critical section 被等待。無法偵測是否已被某個執行緒放棄。例子 include include incl...

四種執行緒池

其他執行緒池 核心執行緒 執行緒池大小 佇列策略 newcachedthreadpool integer.max value synchronousqueue newfixedthreadpool 建立時可以設定引數 建立時可以設定引數 linkedblockingqueue newschedule...