簡體   English   中英

正確使用Win32線程

[英]Proper use of threads Win32

我剛剛學習了Win32編程,並對線程有疑問。 假設我有下面的例子,我想知道在for循環中調用的PrintStuff()函數是在創建的新線程上運行還是在主線程上運行? 謝謝。

    HANDLE hThrd;
    DWORD WINAPI PrintStuff() {
        OutputDebugString("printing stuff");
        return 0;
    }
    int WINAPI WinMain(...) {
        ...
        hThrd = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)PrintStuff, NULL, CREATE_SUSPENDED, &id)
        int i;
        for (i = 0; i < 5; i++) {
            PrintStuff();
        }
        ...
    }

您似乎認為CreateThread以某種方式“標記”要在另一個線程中運行的函數,因此每次調用它都會在另一個線程中運行。 不像那樣。 顧名思義, CreateThread只創建一個新的線程,其入口點是您指定的函數。 調用之后的所有指令仍然在與之前相同的線程中運行,而您指定的函數將在調用CreateThread后的一段時間CreateThread一個單獨的線程中調用一次。

順便提一下,如果要在新創建的線程上使用標准庫中的任何函數,則不應直接使用CreateThread ,而應使用_beginthread


我現在看到你正在指定CREATE_SUSPENDED標志; 因此,除非您在其上調用ResumeThread ,否則新線程將永遠不會運行。

有多種方法可以確定哪個線程正在運行該函數。

1.獲取當前線程ID

GetCurrentThreadId()可以與Windows API一起使用。

C ++中還有很多其他方法。 C ++標准庫還在#include <thread>提供std::this_thread::get_id() ,它可用於獲取ID以獨立於平台的方式進行比較。

使用線程ID,您只需檢查WinMain開頭的線程ID,並將主線程的ID存儲在全局變量中,您可以在PrintStuff中使用該變量。

請注意,標准庫get_id()返回的ID集與GetCurrentThreadId()不同,因此您需要選擇一個。

2.使用線程局部變量。

在使用Visual Studio的Windows平台上,您可以使用__declspec(thread) 如果您有C ++ 14(Visual Studio 2015提供),則可以使用thread_local

使用線程局部變量,如果主線程正在運行該函數,則可以輕松計算出來。

__declspec(thread) bool isMainThread = false;
HANDLE hThrd;
DWORD WINAPI PrintStuff() {
    OutputDebugString("printing stuff");
    // check isMainThread here
    return 0;
}
int WINAPI WinMain(...) {
    isMainThread = true;
    ...
    hThrd = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)PrintStuff, NULL, CREATE_SUSPENDED, &id)
    int i;
    for (i = 0; i < 5; i++) {
        PrintStuff();
    }
    ...
}

線程局部變量可用於存儲線程名稱,而不僅僅是打印一個並不總是易於解釋的線程ID。

3.將參數傳遞給函數,或使用包裝函數

如果您只想以不同的方式打印,可以在創建新線程時使用包裝函數,並使用此函數將參數傳遞給PrintStuff函數。 如果您不想將參數傳遞給PrintStuff來執行不同的操作,您還可以使用包裝函數來設置線程局部變量。 這是您可以為線程命名的地方。

你可以打印threadId來查看使用的線程。

https://msdn.microsoft.com/en-us/library/windows/desktop/ms683183(v=vs.85).aspx

如果要檢查它是否在主線程中打印,可以獲取上面使用的主要threadId並將其與PrintStuff中的threadId進行比較。

使用函數中的GetCurrentThreadId()來知道當前正在執行它的線程。

DWORD WINAPI PrintStuff() {
    DWORD idThread = GetCurrentThreadId();
    printf("Thread ID: %i.\n", idThread);
}

暫無
暫無

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

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