[英]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
,否則新線程將永遠不會運行。
有多種方法可以確定哪個線程正在運行該函數。
GetCurrentThreadId()
可以與Windows API一起使用。
C ++中還有很多其他方法。 C ++標准庫還在#include <thread>
提供std::this_thread::get_id()
,它可用於獲取ID以獨立於平台的方式進行比較。
使用線程ID,您只需檢查WinMain開頭的線程ID,並將主線程的ID存儲在全局變量中,您可以在PrintStuff中使用該變量。
請注意,標准庫get_id()返回的ID集與GetCurrentThreadId()不同,因此您需要選擇一個。
在使用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。
如果您只想以不同的方式打印,可以在創建新線程時使用包裝函數,並使用此函數將參數傳遞給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.