【Demo 0081】获取进程中线程列表
进程为线程提供生存的空间,线程为进程的存在提供了时间,没有线程的存在进程没有存在的意义,一个进程中可以同时具有多个线程,但必须有一个线程,进程生成时创建的第一个线程被称之为主线程,它可以创建子线程,子线程还可以创建孙线程。本练习用于学习如何获取系统中所有的线程,如何获取指定进程中所有线程。
实现方法:
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: }