進程為線程提供生存的空間,線程為進程的存在提供了時間,沒有線程的存在進程沒有存在的意義,一個進程中可以同時具有多個線程,但必須有一個線程,進程生成時創建的第一個線程被稱之為主線程,它可以創建子線程,子線程還可以創建孫線程。本練習用於學習如何獲取系統中所有的線程,如何獲取指定進程中所有線程。
實現方法:
1. 通過CreateToolhelpSnapshot函數創建一線程快照;
2. 使用Thread32First以及Thread32Next函數遍歷系統中所有線程,根據比較線程父進程ID來過濾指定進程的所有線程;
3. 關閉線程快照句柄.
API說明:
1. typedef struct tagTHREADENTRY32 {
DWORD dwSize; // sizeof(THREADENTRY32)
DWORD cntUsage; // 不用了
DWORD th32ThreadID; // 線程ID
DWORD th32OwnerProcessID; // 線程所有的進程ID
LONG tpBasePri; // 基礎線程優先級
LONG tpDeltaPri; // 不用了
DWORD dwFlags; // 不用了
} THREADENTRY32
線程描述信息
1. HANDLE WINAPI CreateToolhelp32Snapshot(DWORD dwFlags, DWORD th32ProcessID);
創建系統快照,當dwFlags=TH32CS_SNAPTHREAD時,僅生成系統中線程部分快照
2. BOOL WINAPI Thread32First(HANDLE hSnapshot, LPTHREADENTRY32 lpt2)
獲取線程快照中第一個線程信息
3. BOOL WINAPI Thread32Next(HANDLE hSnapshot, LPTHREADENTRY32 lpte);
獲取線程快照中下一個線程信息
關鍵代碼:
1: DWORD th32ProcessID = ComboBox_GetItemData(hCmbProcess, ComboBox_GetCurSel(hCmbProcess));
2: HANDLE hSnapThread = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, th32ProcessID);
3: if (INVALID_HANDLE_VALUE != hSnapThread)
4: {
5: THREADENTRY32 te32 = {sizeof(te32)};
6: if (Thread32First(hSnapThread, &te32))
7: {
8: SetWindowText(GetDlgItem(hDlg, IDC_EDTINFO), _T(""));
9:
10: DWORD nCount = 0;
11: do {
12: if (th32ProcessID == te32.th32OwnerProcessID)
13: {
14: AddTextToEdit(GetDlgItem(hDlg, IDC_EDTINFO),
15: _T("Thread: %d\r\n")
16: _T("---------------------------------------\r\n")
17: _T("%-20s 0x%06X(%d)\r\n")
18: _T("%-20s 0x%06X(%d)\r\n")
19: _T("%-20s %d\r\n\r\n"),
20: nCount++,
21: _T("Main Thread ID:"), te32.th32ThreadID, te32.th32ThreadID,
22: _T("Parent Thread ID:"), te32.th32OwnerProcessID, te32.th32OwnerProcessID,
23: _T("Priority Level:"), te32.tpBasePri);
24: }
25: } while (Thread32Next(hSnapThread, &te32));
26: }
27:
28: CloseHandle(hSnapThread);
29: }