我在查询时使用的多个线程,
但在查询结束时如何确定还有多少个线程在执行。
for(int i=1;i<n;i++)
{
AfxBeginThread(AFX_THREADPROC)threadISP,(void*)i);
}
//此处我需要知道每个线程的状态。

解决方案 »

  1.   

    我想根据进程占用CUP的情况判断,但又该如何做。
      

  2.   

    int GetThreadPriority(
      HANDLE hThread   // handle to thread
    );
      

  3.   

    使用WaitForSingleObject(...handOfThread...)或者WaitForMultipleObjects(...handOfThread...) 等待每个线程结束,设置TimeOut,如果在一定的时间范围内线程还没有结束,就TerminateThread
      

  4.   

    但我会同时开的线程数目不定,会很多个。
    对每个线程用下面的函数也不容易。
    GetThreadPriority
    WaitForSingleObject
    能不能直接取得当前进程中所有正在执行的线程的信息?
      

  5.   

    OpenThread 通过线程的ID取得线程的句柄 但要在win2000下用。
      

  6.   

    CreateToolhelp32Snapshot
    Thread32First
    Thread32Next
    用以上几个函数可以遍历一个进程下的所有线程,但也有win2000的限制
    所以最好自己管理自己的线程句柄,用CreateThread建立线程句柄放在数组里,
    什么时候想用就可以去用。
      

  7.   

    注明:这是别人的程序,是我收集的.(第一部分/共二部分)
    以下是在Windows NT下枚举属于一个进程的所有线程(thread)ID的源程序,
    本程序还不完善,没有错误处理也没有优化. 如果有逻辑上的错误,还望网友指正.
    另外,执行本程序需要 pdh.dll !!! //////////////////////////////////////////////////////////////
    // HJPDH.h Header file of HJPDH
    //////////////////////////////////////////////////////////////
    #ifndef HJPDH_H
    #define HJPDH_H//接口函数,本函数将根据指定的进程Id,及其相应的内存映射执行文件名(例:"winlogon.exe")
    //返回该进程的所有线程Id
    //
    //[out] arrThreadId, DWORD数组,返回指定进程的所有线程Id
    //[in]  szFullModuleName, 指定进程的内存映射执行文件名,其格式同
    //      Windows NT task manager中process image name项,例:"winlogon.exe"
    //[in]  dwProcessId, 指定的进程Id, 
    BOOL GetThreadList(CDWordArray& arrThreadId,
                 LPSTR szModuleName,DWORD dwProcessId);BOOL testPDHVersion();
    BOOL OpenPDHSession();
    BOOL AddCounterToQuery(LPCSTR szFullCounterPath);
    BOOL CollectQueryData(DWORD& dwData);
    BOOL ClosePDHSession();BOOL MakeCounterPath(LPSTR szfullPath, 
             LPSTR szObjectName,LPSTR szCounterName,
             LPSTR szInstanceName="*",
             DWORD dwInstanceIndex=(DWORD)-1,
             LPSTR szParentInstance=NULL);int GetProcessInstanceCnt(LPSTR szModuleName);
    int GetProcessInstanceIndex(LPSTR szModuleName,
             DWORD dwProcessId,int instanceCnt);
    int GetProcessThreadCnt(LPSTR szInstanceName,int instanceindex);
    int GetThreadId(LPSTR szModuleName,int threadIndex,int instanceindex);#endif //end define HJPDH_H
    //////////////////////////////////////////////////////////////
    // HJPDH.cpp body file of HJPDH
    //////////////////////////////////////////////////////////////#include "stdafx.h"
    #include "HJPDH.h"HQUERY m_pDhQuery=NULL;
    HCOUNTER m_ThreadCounterHandle=NULL;int GetProcessInstanceCnt(LPSTR szModuleName)
    {
    int instanceCnt;
    instanceCnt = 0;
    char buff[128];
    CString strTmpName;strTmpName = szModuleName;PDH_STATUS  pdhStatus               = ERROR_SUCCESS;
    LPTSTR      szCounterListBuffer     = NULL;
    DWORD       dwCounterListSize       = 0;
    LPTSTR      szInstanceListBuffer    = NULL;
    DWORD       dwInstanceListSize      = 0;
    LPTSTR      szThisInstance          = NULL;
    // Determine the required buffer size for the data. 
    pdhStatus = PdhEnumObjectItems (
                  NULL,                   // reserved
                  NULL,                   // local machine
                  TEXT("Process"),        // object to enumerate
                  szCounterListBuffer,    // pass in NULL buffers
                  &dwCounterListSize,     // an 0 length to get
                  szInstanceListBuffer,   // required size 
                  &dwInstanceListSize,    // of the buffers in chars
                  PERF_DETAIL_WIZARD,     // counter detail level
                  0); if (pdhStatus == ERROR_SUCCESS) 
             {
        // Allocate the buffers and try the call again.
        szCounterListBuffer = (LPTSTR)malloc (
                               (dwCounterListSize * sizeof (TCHAR)));
                 szInstanceListBuffer = (LPTSTR)malloc (
                               (dwInstanceListSize * sizeof (TCHAR)));
                 if ((szCounterListBuffer != NULL) &&
                               (szInstanceListBuffer != NULL)) 
                 {
                     pdhStatus = PdhEnumObjectItems (
                          NULL,   // reserved
                          NULL,   // local machine
                          TEXT("Process"), // object to enumerate
                          szCounterListBuffer,    // passing in NULL buffers
                          &dwCounterListSize,     // passing in 0
                          szInstanceListBuffer,   
                          &dwInstanceListSize,    
                          PERF_DETAIL_WIZARD,     // counter detail level
                          0);     
                
          if (pdhStatus == ERROR_SUCCESS) 
                   {
           // Walk the return instance list.
                    for (szThisInstance = szInstanceListBuffer;
    *szThisInstance != 0;
    szThisInstance += lstrlen(szThisInstance) + 1) 
                    {
    sprintf (buff,"%s", szThisInstance);
    if(strTmpName.CompareNoCase(buff)==0)
    instanceCnt++;
                    }
                }
            } 
            else 
            {
       return instanceCnt;
            }if (szCounterListBuffer != NULL) 
        free (szCounterListBuffer);if (szInstanceListBuffer != NULL) 
        free (szInstanceListBuffer);

    else 
    {
    return instanceCnt;   
    }return instanceCnt;
    }int GetProcessThreadCnt(LPSTR szInstanceName,int instanceindex)
    {
    BOOL rtn;
    char szFullCounterPath[256];
    DWORD dwThreadCnt;dwThreadCnt = 0;rtn = OpenPDHSession();
    if(rtn==FALSE)
    return dwThreadCnt;rtn = MakeCounterPath(szFullCounterPath, "Process",
                 "Thread Count", szInstanceName,instanceindex);
    if(rtn==FALSE)
        return FALSE;rtn = AddCounterToQuery(szFullCounterPath);
    if(rtn==FALSE)
    return FALSE;// get thread count of specified Process
    rtn = CollectQueryData(dwThreadCnt);
    if(rtn==FALSE)
    return FALSE;ClosePDHSession();return dwThreadCnt;
    }int GetThreadId(LPSTR szModuleName,int threadIndex,int instanceindex)
    {
    BOOL rtn;
    char szFullCounterPath[256];
    char szBuff[256];
    char szIndex[10];
    DWORD dwThreadId;dwThreadId = 0;sprintf(szIndex,"%d",threadIndex);
    strcpy(szBuff,szModuleName);
    strcat(szBuff,"/");
    strcat(szBuff,szIndex);rtn = OpenPDHSession();
    if(rtn==FALSE)
    return dwThreadId;rtn = MakeCounterPath(szFullCounterPath, "Thread",
                     "ID Thread", szBuff,instanceindex);
    if(rtn==FALSE)
    return FALSE;rtn = AddCounterToQuery(szFullCounterPath);
    if(rtn==FALSE)
    return FALSE;// get thread id of specified thread
    rtn = CollectQueryData(dwThreadId);
    if(rtn==FALSE)
    return FALSE;ClosePDHSession();return dwThreadId;
    }
      

  8.   

    注明:以下是别人的程序,是我收集的(第一部分/共二部分)
    以下是在Windows NT下枚举属于一个进程的所有线程(thread)ID的源程序,
    本程序还不完善,没有错误处理也没有优化. 如果有逻辑上的错误,还望网友指正.
    另外,执行本程序需要 pdh.dll !!!//////////////////////////////////////////////////////////////
    // HJPDH.h Header file of HJPDH
    //////////////////////////////////////////////////////////////
    #ifndef HJPDH_H
    #define HJPDH_H//接口函数,本函数将根据指定的进程Id,及其相应的内存映射执行文件名(例:"winlogon.exe")
    //返回该进程的所有线程Id
    //
    //[out] arrThreadId, DWORD数组,返回指定进程的所有线程Id
    //[in]  szFullModuleName, 指定进程的内存映射执行文件名,其格式同
    //      Windows NT task manager中process image name项,例:"winlogon.exe"
    //[in]  dwProcessId, 指定的进程Id, 
    BOOL GetThreadList(CDWordArray& arrThreadId,
                 LPSTR szModuleName,DWORD dwProcessId);BOOL testPDHVersion();
    BOOL OpenPDHSession();
    BOOL AddCounterToQuery(LPCSTR szFullCounterPath);
    BOOL CollectQueryData(DWORD& dwData);
    BOOL ClosePDHSession();BOOL MakeCounterPath(LPSTR szfullPath, 
             LPSTR szObjectName,LPSTR szCounterName,
             LPSTR szInstanceName="*",
             DWORD dwInstanceIndex=(DWORD)-1,
             LPSTR szParentInstance=NULL);int GetProcessInstanceCnt(LPSTR szModuleName);
    int GetProcessInstanceIndex(LPSTR szModuleName,
             DWORD dwProcessId,int instanceCnt);
    int GetProcessThreadCnt(LPSTR szInstanceName,int instanceindex);
    int GetThreadId(LPSTR szModuleName,int threadIndex,int instanceindex);#endif //end define HJPDH_H
    //////////////////////////////////////////////////////////////
    // HJPDH.cpp body file of HJPDH
    //////////////////////////////////////////////////////////////#include "stdafx.h"
    #include "HJPDH.h"HQUERY m_pDhQuery=NULL;
    HCOUNTER m_ThreadCounterHandle=NULL;int GetProcessInstanceCnt(LPSTR szModuleName)
    {
    int instanceCnt;
    instanceCnt = 0;
    char buff[128];
    CString strTmpName;strTmpName = szModuleName;PDH_STATUS  pdhStatus               = ERROR_SUCCESS;
    LPTSTR      szCounterListBuffer     = NULL;
    DWORD       dwCounterListSize       = 0;
    LPTSTR      szInstanceListBuffer    = NULL;
    DWORD       dwInstanceListSize      = 0;
    LPTSTR      szThisInstance          = NULL;
    // Determine the required buffer size for the data. 
    pdhStatus = PdhEnumObjectItems (
                  NULL,                   // reserved
                  NULL,                   // local machine
                  TEXT("Process"),        // object to enumerate
                  szCounterListBuffer,    // pass in NULL buffers
                  &dwCounterListSize,     // an 0 length to get
                  szInstanceListBuffer,   // required size 
                  &dwInstanceListSize,    // of the buffers in chars
                  PERF_DETAIL_WIZARD,     // counter detail level
                  0); if (pdhStatus == ERROR_SUCCESS) 
             {
        // Allocate the buffers and try the call again.
        szCounterListBuffer = (LPTSTR)malloc (
                               (dwCounterListSize * sizeof (TCHAR)));
                 szInstanceListBuffer = (LPTSTR)malloc (
                               (dwInstanceListSize * sizeof (TCHAR)));
                 if ((szCounterListBuffer != NULL) &&
                               (szInstanceListBuffer != NULL)) 
                 {
                     pdhStatus = PdhEnumObjectItems (
                          NULL,   // reserved
                          NULL,   // local machine
                          TEXT("Process"), // object to enumerate
                          szCounterListBuffer,    // passing in NULL buffers
                          &dwCounterListSize,     // passing in 0
                          szInstanceListBuffer,   
                          &dwInstanceListSize,    
                          PERF_DETAIL_WIZARD,     // counter detail level
                          0);     
                
          if (pdhStatus == ERROR_SUCCESS) 
                   {
           // Walk the return instance list.
                    for (szThisInstance = szInstanceListBuffer;
    *szThisInstance != 0;
    szThisInstance += lstrlen(szThisInstance) + 1) 
                    {
    sprintf (buff,"%s", szThisInstance);
    if(strTmpName.CompareNoCase(buff)==0)
    instanceCnt++;
                    }
                }
            } 
            else 
            {
       return instanceCnt;
            }if (szCounterListBuffer != NULL) 
        free (szCounterListBuffer);if (szInstanceListBuffer != NULL) 
        free (szInstanceListBuffer);

    else 
    {
    return instanceCnt;   
    }return instanceCnt;
    }int GetProcessThreadCnt(LPSTR szInstanceName,int instanceindex)
    {
    BOOL rtn;
    char szFullCounterPath[256];
    DWORD dwThreadCnt;dwThreadCnt = 0;rtn = OpenPDHSession();
    if(rtn==FALSE)
    return dwThreadCnt;rtn = MakeCounterPath(szFullCounterPath, "Process",
                 "Thread Count", szInstanceName,instanceindex);
    if(rtn==FALSE)
        return FALSE;rtn = AddCounterToQuery(szFullCounterPath);
    if(rtn==FALSE)
    return FALSE;// get thread count of specified Process
    rtn = CollectQueryData(dwThreadCnt);
    if(rtn==FALSE)
    return FALSE;ClosePDHSession();return dwThreadCnt;
    }int GetThreadId(LPSTR szModuleName,int threadIndex,int instanceindex)
    {
    BOOL rtn;
    char szFullCounterPath[256];
    char szBuff[256];
    char szIndex[10];
    DWORD dwThreadId;dwThreadId = 0;sprintf(szIndex,"%d",threadIndex);
    strcpy(szBuff,szModuleName);
    strcat(szBuff,"/");
    strcat(szBuff,szIndex);rtn = OpenPDHSession();
    if(rtn==FALSE)
    return dwThreadId;rtn = MakeCounterPath(szFullCounterPath, "Thread",
                     "ID Thread", szBuff,instanceindex);
    if(rtn==FALSE)
    return FALSE;rtn = AddCounterToQuery(szFullCounterPath);
    if(rtn==FALSE)
    return FALSE;// get thread id of specified thread
    rtn = CollectQueryData(dwThreadId);
    if(rtn==FALSE)
    return FALSE;ClosePDHSession();return dwThreadId;
    }
      

  9.   

    注明:以下是别人的程序,是我收集的(第二部分/共二部分)
    int GetProcessInstanceIndex(LPSTR szModuleName,
                      DWORD dwProcessId,int instanceCnt)
    {
    BOOL rtn;
    int index;
    char szFullCounterPath[256];
    DWORD dwTmpProcessId;index = -1;rtn = OpenPDHSession();
    if(rtn==FALSE)
    return index;for(int i=0;i<instanceCnt;i++)
    {
    rtn = MakeCounterPath(szFullCounterPath, 
                               "Process","ID Process", szModuleName,i);
    if(rtn==FALSE)
    return FALSE;rtn = AddCounterToQuery(szFullCounterPath);
    if(rtn==FALSE)
    return FALSE;// get specified Process's ID
    rtn = CollectQueryData(dwTmpProcessId);
    if(rtn==FALSE)
    return FALSE;if(dwTmpProcessId==dwProcessId)
    {
    index = i;
    break;
    }rtn = PdhRemoveCounter(m_ThreadCounterHandle);
    }//end forClosePDHSession();return index;
    }BOOL GetThreadList(CDWordArray& arrThreadId, 
                        LPSTR szFullModuleName,DWORD dwProcessId)
    {
    BOOL rtn;//testPDHVersion();// get module name like "notepad" 
    char drive[_MAX_DRIVE];
    char dir[_MAX_DIR];
    char fname[_MAX_FNAME];
    char ext[_MAX_EXT];_splitpath( szFullModuleName, drive, dir, fname, ext );int processInsCnt, processInsIndex, processThreadCnt,dwThreadId;processInsCnt = GetProcessInstanceCnt(fname);if(processInsCnt==0)
    return FALSE;if(processInsCnt>1)
    processInsIndex = GetProcessInstanceIndex(fname,dwProcessId,processInsCnt);
    else
    processInsIndex =0;if(processInsIndex==-1)
    return FALSE;processThreadCnt = GetProcessThreadCnt(fname,processInsIndex);char buff[1024];
    char tmpStr[64];buff[0]='\0';
    for(int i=0;i<processThreadCnt;i++)
    {
    dwThreadId = GetThreadId(fname,i,processInsIndex);
    arrThreadId.Add(dwThreadId);
    sprintf(tmpStr,"Thread %d: %d\n",i,dwThreadId);
    strcat(buff,tmpStr);
    }
    AfxMessageBox(buff);return TRUE;
    }BOOL testPDHVersion()
    {
    DWORD dwVersion;PDH_STATUS pdhStatus=PdhGetDllVersion(&dwVersion);if(pdhStatus==ERROR_SUCCESS)
    {
    switch(dwVersion)
    {
    case PDH_CVERSION_WIN40:
    AfxMessageBox("The file version is Windows NT 4.0. ");
    break;//case PDH_CVERSION_WIN50:
    // AfxMessageBox("The file version is Windows 2000. ");
    // break;
    default:
    // AfxMessageBox("The file version is Unknown");
    break;
    }//end of switch
    return TRUE;
    }return FALSE;
    }BOOL OpenPDHSession()
    {
    PDH_STATUS pdhStatus;pdhStatus = PdhOpenQuery(NULL, 0, &m_pDhQuery);if(pdhStatus==ERROR_SUCCESS) 
    return TRUE;
    else
    return FALSE;
    }BOOL AddCounterToQuery(LPCSTR szFullCounterPath)
    {
    PDH_STATUS pdhStatus;pdhStatus = PdhAddCounter(
    m_pDhQuery,              
    szFullCounterPath,  
    0, 
    &m_ThreadCounterHandle);if(pdhStatus==ERROR_SUCCESS) 
    return TRUE;
    else
    return FALSE;
    }BOOL MakeCounterPath(LPSTR szfullPath, LPSTR szObjectName,
                     LPSTR szCounterName,LPSTR szInstanceName,
                     DWORD dwInstanceIndex,LPSTR szParentInstance)
    {
    PDH_STATUS pdhStatus;
    PDH_COUNTER_PATH_ELEMENTS element;char buff[512];
    DWORD chBufferSize = 512;element.szMachineName = NULL;
        element.szObjectName = szObjectName; //"Process"
        element.szInstanceName = szInstanceName;
        element.szParentInstance = szParentInstance;
        element.dwInstanceIndex = dwInstanceIndex; //DWORD(-1); 
        element.szCounterName = szCounterName; //"ID Process"pdhStatus = PdhMakeCounterPath(
    &element,
    buff,  
    &chBufferSize,   
    0             
    ); if(pdhStatus==ERROR_SUCCESS) 
    {
    strcpy(szfullPath,buff);
    return TRUE;
    }
    else
    return FALSE;
    }BOOL CollectQueryData(DWORD &dwData)
    {
    PDH_STATUS pdhStatus;
    PDH_FMT_COUNTERVALUE fmtValue;
    DWORD ctrType;// Get the current data values.
    pdhStatus = PdhCollectQueryData (m_pDhQuery);
    if(pdhStatus!=ERROR_SUCCESS) 
    return FALSE;char buff[1024];     // Get the current value of this counter.
         pdhStatus = PdhGetFormattedCounterValue (m_ThreadCounterHandle,
                                                  PDH_FMT_LONG,
                                                  &ctrType,
                                                  &fmtValue);if(pdhStatus != ERROR_SUCCESS) 
    return FALSE; dwData = fmtValue.longValue;//sprintf(buff, TEXT("value is:%d"), fmtValue.longValue);
    //AfxMessageBox(buff);return TRUE;
    }BOOL ClosePDHSession()
    {
    PDH_STATUS pdhStatus;pdhStatus = PdhCloseQuery(m_pDhQuery);if(pdhStatus==ERROR_SUCCESS) 
    return TRUE;
    else
    return FALSE;
    }
      

  10.   

    最好还是你自己管理自己的线程;每开一个线程,就把此线程的指针放在一个CObArray数组中,要判断时从数组头到尾用WaitForSingleObject看看有多少线程在运行就行了!
      

  11.   

    再问一下:在windows2000中最多支持多少个进程每个进程最多支持多少个线程。