線程有兩種,分別叫用戶界面線程和工作者線程,很多人誤以為這兩個種類是在線程最初建立時為其賦予的天生的屬性,實際上它們的區別不在於建立時,而在於運行時是否創建了消息隊列,任何線程在最初建立時是壹樣的。
無論是系統在啟動窗口程序時為其建立壹個主線程,還是程序員在主線程運行時調用CreateThread建立壹個新線程,內部過程以及為線程建立的內部數據結構是壹樣的,都是調用Ntdll.dll的RtlUserThreadStart函數並傳入線程入口指令地址和壹個線程參數(系統啟動主線程時傳入的線程參數為0)。這時它們都沒有自己的線程消息隊列,都是工作者線程。但是窗口程序的主線程往往在啟動後很快建立壹個窗口並循環調用GetMessage抓取消息,而壹旦線程調用壹個與圖形用戶界面有關的函數,如GetMessage/PeekMessage檢查消息隊列或建立壹個窗口,系統就會為該線程分配壹些與用戶界面相關的資源,尤其是分配壹個用於管理消息隊列的THREADINFO結構,這時線程的消息隊列就建立起來,主線程也就轉變為用戶界面線程。