創建一個在調用進程的虛擬地址空間內執行的線程。
要創建在另一個進程的虛擬地址空間中運行的線程,請使用 CreateRemoteThread函數。
語法
HANDLE CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes,SIZE_T dwStackSize,LPTHREAD_START_ROUTINE lpStartAddress,__drv_aliasesMem LPVOID lpParameter,DWORD dwCreationFlags,LPDWORD lpThreadId
);
參數
- lpThreadAttributes
指向SECURITY_ATTRIBUTES 結構的指針,該結構確定子進程是否可以繼承返回的句柄。如果 lpThreadAttributes
為NULL
,則無法繼承句柄。
結構的lpSecurityDescriptor
成員為新線程指定安全描述符。如果lpThreadAttributes
為NULL,則線程獲取默認安全描述符。線程的默認安全描述符中的ACL
來自創建者的主要標志。
- dwStackSize
堆棧的初始大小,以字節為單位。系統將此值四舍五入到最近的頁面。如果此參數為零,則新線程使用可執行文件的默認大小。有關更多信息,請參閱線程堆棧大小。
- lpStartAddress
指向由線程執行的應用程序定義函數的指針。該指針表示線程的起始地址。有關線程函數的更多信息,請參見 ThreadProc
- lpParameter
指向要傳遞給線程的變量的指針。
- dwCreationFlags
控制線程創建的標志。
值 | 含義 |
---|---|
0 | 該線程在創建后立即運行。 |
CREATE_SUSPENDEDs 0x00000004 | 線程是在掛起狀態下創建的,并且在調用ResumeThread函數之前不會運行 。 |
STACK_SIZE_PARAM_IS_A_RESERVATION 0x00010000在 | 所述dwStackSize參數指定堆棧的初始保留大小。如果未指定此標志,則dwStackSize指定提交大小。 |
- lpThreadId
指向接收線程標識符的變量的指針。如果此參數為 NULL,則不返回線程標識符。
返回值
如果函數成功,則返回值是新線程的句柄。
如果函數失敗,則返回值為NULL
。要獲取擴展錯誤信息,請調用 GetLastError。
請注意,即使lpStartAddress
指向數據,代碼或無法訪問,CreateThread
也可能成功 。如果線程運行時起始地址無效,則發生異常,并且線程終止。由于無效的起始地址導致的線程終止被視為線程進程的錯誤退出。此行為類似于CreateProcess的異步特性,即使它引用無效或缺少動態鏈接庫(DLL),也會創建該進程。
備注
進程可以創建的線程數受可用虛擬內存的限制。默認情況下,每個線程都有一兆字節的堆棧空間。因此,您最多可以創建2,048個線程。如果減小默認堆棧大小,則可以創建更多線程。但是,如果為每個處理器創建一個線程并構建應用程序隊列,應用程序維護上下文信息,則應用程序將具有更好的性能。在處理下一個隊列中的請求之前,線程將處理隊列中的所有請求。
使用THREAD_ALL_ACCESS
訪問權限創建新的線程句柄。如果在創建線程時未提供安全描述符,則使用創建線程的進程的主令牌為新線程構造默認安全描述符。當調用者嘗試使用OpenThread函數訪問該線程時,將根據此安全描述符評估調用者的有效令牌以授予或拒絕訪問權限。
調用GetCurrentThread 函數時,新創建的線程對自身具有完全訪問權限。
Windows Server 2003: 線程對自身的訪問權限是通過根據為線程構造的默認安全描述符評估創建線程的進程的主令牌來計算的。如果在遠程進程中創建線程,則使用遠程進程的主令牌。因此,在調用GetCurrentThread時,新創建的線程可能會減少對自身的訪問權限。某些訪問權限(包括THREAD_SET_THREAD_TOKEN
和THREAD_GET_CONTEXT
)可能不存在,從而導致意外故障。因此,建議不要在模仿其他用戶時創建線程。
如果線程是在可運行狀態下創建的(即,如果未使用CREATE_SUSPENDED
標志),則線程可以在CreateThread
返回之前開始運行,特別是在調用者接收到創建的線程的句柄和標識符之前。
線程執行從lpStartAddress
參數指定的函數開始。如果此函數返回,則DWORD
返回值用于在對ExitThread函數的隱式調用中終止線程 。使用 GetExitCodeThread函數獲取線程的返回值。
創建的線程的線程優先級為THREAD_PRIORITY_NORMAL
。使用 GetThreadPriority和 SetThreadPriority函數來獲取和設置線程的優先級值。
當線程終止時,線程對象獲得信號狀態,滿足在對象上等待的任何線程。
線程對象保留在系統中,直到線程終止并且通過調用CloseHandle關閉了它的所有句柄。
ExitProcess, ExitThread, CreateThread
, CreateRemoteThread的功能,以及正在啟動的處理(如通過一個調用的結果 CreateProcess)的過程中是彼此之間串行化。這些事件中只有一個可以一次發生在地址空間中。這意味著以下限制包含:
在進程啟動和DLL初始化例程期間,可以創建新線程,但是在為進程執行DLL初始化之前它們不會開始執行。
進程中只有一個線程可以一次處于DLL初始化或分離例程中。
在DLL初始化或分離例程中沒有線程之前,ExitProcess不會完成。
調用C運行時庫(CRT)的可執行文件中的線程應使用_beginthreadex和_endthreadex函數進行線程管理,而不是 CreateThread
和 ExitThread ; 這需要使用CRT的多線程版本。如果使用CreateThread
創建的線程調用CRT,則CRT可以在低內存條件下終止進程。
Windows Phone 8.1: Windows Phone 8.1及更高版本上的Windows Phone應用商店支持此功能。
Windows 8.1和Windows Server 2012 R2:Windows 8.1,Windows Server 2012 R2及更高版本上的Windows應用商店應用程序支持此功能。
例子
有關示例,請參閱 創建線程。