我在查询时使用的多个线程,
但在查询结束时如何确定还有多少个线程在执行。
for(int i=1;i<n;i++)
{
AfxBeginThread(AFX_THREADPROC)threadISP,(void*)i);
}
//此处我需要知道每个线程的状态。
但在查询结束时如何确定还有多少个线程在执行。
for(int i=1;i<n;i++)
{
AfxBeginThread(AFX_THREADPROC)threadISP,(void*)i);
}
//此处我需要知道每个线程的状态。
解决方案 »
- 请问VC 如何从压缩包中读取bitmap并显示出来?
- 用DLL做声音类连接出错的问题???
- CHtmlView中不支持相对路径?
- 关于使用VC6编译连接时黑屏问题,超常郁闷,请求帮助!!!!!!
- 请问这个编译错误如何解决:msvcrtd.lib(MSVCRTD.dll) : error LNK2005: _strncpy already defined in libcmtd.lib(strncpy.obj)
- 大家给个建议吧 有用的就给分
- 如何更改CListCtrl控件中显示每一行中的字体大小
- 谁知道autocad2000的序列号和CD-KEY?急!!
- 有谁知道与CSS有关的COM接口啊?
- 不知大家在用vc++时是否遇到过这样的问题?
- 类似Word XP的工具栏是怎么做的?
- 小弟有两道题请各位帮忙
HANDLE hThread // handle to thread
);
对每个线程用下面的函数也不容易。
GetThreadPriority
WaitForSingleObject
能不能直接取得当前进程中所有正在执行的线程的信息?
Thread32First
Thread32Next
用以上几个函数可以遍历一个进程下的所有线程,但也有win2000的限制
所以最好自己管理自己的线程句柄,用CreateThread建立线程句柄放在数组里,
什么时候想用就可以去用。
以下是在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;
}
以下是在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;
}
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;
}