获取线程状态

本文分享了一段用于获取Windows线程当前状态(挂起或终止)的代码,包括线程状态枚举、等待原因枚举等。通过调用NtQuerySystemInformation函数查询系统信息,可以获取指定进程中的线程详细信息,从而判断线程是否被挂起或正常运行。

原文:http://hi.baidu.com/combojiang/item/0fe8485b6253140de7c4a520

好久没顾得上写blog了,感谢一直关注本blog的朋友。获取线程当前状态,是挂起还是终止,没有直接的API.这里把自己经常用的这段代码贴出来,与大家分享吧。

#include <stdio.h>
#include <windows.h>
#include <winbase.h>
#include <ntsecapi.h>


#define UNICODE
#define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0)
#define STATUS_SUCCESS              ((NTSTATUS) 0x00000000)
#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS) 0xC0000004)
#define SystemProcessesAndThreadsInformation    5
#define NTAPI    __stdcall

typedef enum _THREAD_STATE
{
    StateInitialized,
    StateReady,
    StateRunning,
    StateStandby,
    StateTerminated,
    StateWait,
    StateTransition,
    StateUnknown
}THREAD_STATE;

typedef enum _KWAIT_REASON
{
    Executive,
    FreePage,
    PageIn,
    PoolAllocation,
    DelayExecution,
    Suspended,
    UserRequest,
    WrExecutive,
    WrFreePage,
    WrPageIn,
    WrPoolAllocation,
    WrDelayExecution,
    WrSuspended,
    WrUserRequest,
    WrEventPair,
    WrQueue,
    WrLpcReceive,
    WrLpcReply,
    WrVirtualMemory,
    WrPageOut,
    WrRendezvous,
    Spare2,
    Spare3,
    Spare4,
    Spare5,
    Spare6,
    WrKernel,
    MaximumWaitReason
}KWAIT_REASON;

typedef NTSTATUS (WINAPI *PNTRAISE)(NTSTATUS,
                                    ULONG,
                                    ULONG,
                                    PULONG,
                                    UINT,
                                    PULONG);   


typedef LONG NTSTATUS;
typedef LONG    KPRIORITY;

typedef struct _CLIENT_ID {
    DWORD        UniqueProcess;
    DWORD        UniqueThread;
} CLIENT_ID, * PCLIENT_ID;


typedef struct _VM_COUNTERS {
    SIZE_T        PeakVirtualSize;
    SIZE_T        VirtualSize;
    ULONG        PageFaultCount;
    SIZE_T        PeakWorkingSetSize;
    SIZE_T        WorkingSetSize;
    SIZE_T        QuotaPeakPagedPoolUsage;
    SIZE_T        QuotaPagedPoolUsage;
    SIZE_T        QuotaPeakNonPagedPoolUsage;
    SIZE_T        QuotaNonPagedPoolUsage;
    SIZE_T        PagefileUsage;
    SIZE_T        PeakPagefileUsage;
} VM_COUNTERS;


typedef struct _SYSTEM_THREAD_INFORMATION {
    LARGE_INTEGER   KernelTime;
    LARGE_INTEGER   UserTime;
    LARGE_INTEGER   CreateTime;
    ULONG            WaitTime;
    PVOID            StartAddress;
    CLIENT_ID        ClientId;
    KPRIORITY        Priority;
    KPRIORITY        BasePriority;
    ULONG            ContextSwitchCount;
    LONG            State;
    LONG            WaitReason;
} SYSTEM_THREAD_INFORMATION, * PSYSTEM_THREAD_INFORMATION;



typedef struct _SYSTEM_PROCESS_INFORMATION {
    ULONG            NextEntryDelta;
    ULONG            ThreadCount;
    ULONG            Reserved1[6];
    LARGE_INTEGER   CreateTime;
    LARGE_INTEGER   UserTime;
    LARGE_INTEGER   KernelTime;
    UNICODE_STRING ProcessName;
    KPRIORITY        BasePriority;
    ULONG            ProcessId;
    ULONG            InheritedFromProcessId;
    ULONG            HandleCount;
    ULONG            Reserved2[2];
    VM_COUNTERS        VmCounters;
    IO_COUNTERS        IoCounters;
    SYSTEM_THREAD_INFORMATION Threads[5];
} SYSTEM_PROCESS_INFORMATION, * PSYSTEM_PROCESS_INFORMATION;



typedef DWORD (WINAPI* PQUERYSYSTEM)(UINT, PVOID, DWORD,PDWORD);

/************************************************************************/
/* 函数说明:
   参数:dwThreadID 代表线程ID ,这里主要是验证线程的ID
             szProcessName,表示线程所在的进程名

返回值:
       true: 表示线程被挂起
       false: 表示线程正常。

*/
/************************************************************************/

BOOL IsThreadSuspend(DWORD dwThreadID,wchar_t *szProcessName)
{
    ULONG cbBuffer = 0x5000;
   
    BOOL bRet = FALSE;

    LPVOID pBuffer = NULL;
    NTSTATUS Status;


    DWORD b=0;

    PQUERYSYSTEM NtQuerySystemInformation;
    PSYSTEM_PROCESS_INFORMATION pInfo ;

    NtQuerySystemInformation = (PQUERYSYSTEM) GetProcAddress(
        LoadLibrary( "ntdll.dll" ),
        "NtQuerySystemInformation" );

    do
    {
        pBuffer = malloc(cbBuffer);
        if (pBuffer == NULL)
        {
            break;
        }

        Status = NtQuerySystemInformation(
            SystemProcessesAndThreadsInformation,
            pBuffer, cbBuffer, NULL);

        if (Status == STATUS_INFO_LENGTH_MISMATCH)
        {
            free(pBuffer);
            cbBuffer *= 2;
        }
        else if (!NT_SUCCESS(Status))
        {
            free(pBuffer);
        }

    }   while (Status == STATUS_INFO_LENGTH_MISMATCH);


    pInfo = (PSYSTEM_PROCESS_INFORMATION)pBuffer;

    for (;;)
    {


        if (pInfo->NextEntryDelta == 0)
            break;
        if(pInfo->ProcessName.Buffer!=NULL &&
            !_wcsicmp(pInfo->ProcessName.Buffer,szProcessName))
        {

            for(b=0;b<pInfo->ThreadCount ;b++)
            {
                if(pInfo->Threads[b].ClientId.UniqueThread == dwThreadID ) //找到线程              
                {

                    if(pInfo->Threads[b].State == StateWait && pInfo->Threads[b].WaitReason == Suspended) //线程被挂起
                    {
                        bRet = TRUE;
                        break;
                    }
                }
            }
            break;
       
        }
        pInfo = (PSYSTEM_PROCESS_INFORMATION)(((PUCHAR)pInfo) +    pInfo->NextEntryDelta);
    }

    free(pBuffer);
    return bRet;
}   


/**************************************************************/
/*判断线程是否被终止 , 如果终止返回FALSE,如果还活着返回TRUE
/**************************************************************/

BOOL IsThreadAlive(DWORD dwThreadID)
{
    BOOL bRet = FALSE;
    DWORD ExitCode = 0;

    HANDLE hThread = OpenThread(THREAD_QUERY_INFORMATION,FALSE,dwThreadID);
    if(hThread != NULL)
    {
        if(GetExitCodeThread(hThread,&ExitCode))
        {
            if( ExitCode == STILL_ACTIVE)
                bRet = TRUE;
        }

        CloseHandle(hThread);
    }

    return bRet;
}

int _tmain(int argc, _TCHAR* argv[])
{

   
    BOOL bRET =IsThreadSuspend(2320,L"EXPLORER.EXE");


    if(bRET)
    {
        printf(" 2320线程被挂起了!");
    }
    return 0;
}
在MFC中,可以通过以下几种常见方法获取线程状态: ### 使用`GetExitCodeThread`函数 `GetExitCodeThread`是Windows API函数,可用于获取指定线程的退出代码,通过退出代码可以间接判断线程状态。如果线程仍在运行,退出代码为`STILL_ACTIVE`。示例代码如下: ```cpp #include <windows.h> #include <iostream> // 线程函数 DWORD WINAPI MyThreadFunction(LPVOID lpParam) { // 模拟线程工作 Sleep(2000); return 0; } int main() { HANDLE hThread = CreateThread(NULL, 0, MyThreadFunction, NULL, 0, NULL); if (hThread == NULL) { std::cerr << "Failed to create thread." << std::endl; return 1; } DWORD dwExitCode; if (GetExitCodeThread(hThread, &dwExitCode)) { if (dwExitCode == STILL_ACTIVE) { std::cout << "Thread is still running." << std::endl; } else { std::cout << "Thread has exited with code: " << dwExitCode << std::endl; } } else { std::cerr << "Failed to get thread exit code." << std::endl; } // 等待线程结束 WaitForSingleObject(hThread, INFINITE); CloseHandle(hThread); return 0; } ``` ### 通过`CWinThread`对象 使用`AfxBeginThread`创建线程时会返回一个`CWinThread`对象指针,通过该对象可以获取线程状态。可以通过检查线程的`m_bAutoDelete`、`m_hThread`等成员变量来辅助判断线程状态。示例代码如下: ```cpp #include <afxwin.h> // 线程函数 UINT MyWorkerThread(LPVOID pParam) { // 模拟线程工作 Sleep(2000); return 0; } void CheckThreadStatus() { CWinThread* pThread = AfxBeginThread(MyWorkerThread, NULL); if (pThread != NULL) { if (pThread->m_hThread != NULL) { // 线程已启动 // 可以进一步检查是否仍在运行 DWORD dwExitCode; if (GetExitCodeThread(pThread->m_hThread, &dwExitCode)) { if (dwExitCode == STILL_ACTIVE) { // 线程仍在运行 } else { // 线程已退出 } } } } } ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值