使用下面的程序终止每个线程后,我需要每次都用ids打印剩余的线程,我正在使用GetExitCodeThread函数,但是它返回了一些垃圾值。我可能做错了什么?还有,怎么样在获得exitCode正确后打印剩余的线程?
#define NUM_THREADS 10
#include <windows.h>
#include <stdio.h>
#include <process.h>
typedef struct
{
int Id;
HANDLE hTerminate;
} ThreadArgs;
unsigned _stdcall ThreadFunc( void *pArgs )
{
LPDWORD exitCode;
HANDLE hTerminate = ((ThreadArgs *)pArgs)->hTerminate;
int id = ((ThreadArgs *)pArgs)->Id;
// run until we are told to terminate while (1)
while(1)
{
// Check to see if we should terminate
if (WaitForSingleObject(hTerminate, 0) == WAIT_OBJECT_0)
{
// Terminate Thread - we call ResetEvent to
// return the terminate thread to its non-
// signaled state, then exit the while() loop
printf ("Terminating Thread %d\n", id);
GetExitCodeThread(hTerminate,exitCode);
printf("%d",exitCode);
ResetEvent(hTerminate);
break;
}
// we can do our work now ...
// simulate the case that it takes
// to do the work the thread has to do
Sleep(1000);
}
_endthreadex(0);
return 0;
}
int main(int argc, char* argv[])
{
int i=0;
unsigned int threadID[NUM_THREADS];
HANDLE hThread[NUM_THREADS];
ThreadArgs threadArgs[NUM_THREADS];
// Create 10 threads
printf("Total number of threads= %d\n", NUM_THREADS);
for (i = 0; i < NUM_THREADS;i++)
{
printf("Thread number %d \n",i);
}
for (int i = 0; i<NUM_THREADS;i++)
{
threadArgs[i].Id = i;
threadArgs[i].hTerminate = CreateEvent(NULL,TRUE,FALSE,NULL);
hThread[i] = (HANDLE)_beginthreadex(NULL,0,&ThreadFunc,&threadArgs[i], 0, &threadID[i]);
}
printf("To kill a thread (gracefully), press 0-9, "" then <Enter>. \n");
printf("Press any other key to exit.\n");
while (1)
{
int c = getc(stdin);
if (c == '\n')
continue;
if (c < '0' || c > '9')
break;
SetEvent(threadArgs[c -'0'].hTerminate);
}
return 0;
}
答案 0 :(得分:0)
GetExitCodeThread()
期望HANDLE
到主题对象,但您将HANDLE
传递给事件对象 。您还传递一个未初始化的指针,将退出代码写入。因此,GetExitCodeThread()
将失败并显示您忽略的错误,并且不会为退出代码分配任何有意义的值。
并不重要,因为GetExitCodeThread()
无法在仍在运行的线程内调用,它会将退出代码设置为STILL_ACTIVE
。您应该在与被终止的线程不同的线程中调用GetExitCodeThread()
。
尝试更像这样的东西:
#include <windows.h>
#include <stdio.h>
#include <process.h>
#define MAX_THREADS 10
typedef struct
{
int Id;
DWORD dwThreadId;
HANDLE hThread;
HANDLE hTerminate;
} ThreadArgs;
unsigned __stdcall ThreadFunc( void *arg )
{
ThreadArgs *pArgs = (ThreadArgs *) arg;
// run until we are told to terminate while (1)
while(1)
{
// Check to see if we should terminate
if (WaitForSingleObject(pArgs->hTerminate, 0) == WAIT_OBJECT_0)
{
// Terminate Thread - exit the while() loop
printf ("Thread %d terminate signal detected\n", pArgs->Id);
break;
}
// we can do our work now ...
// simulate the case that it takes
// to do the work the thread has to do
Sleep(1000);
}
return 0;
}
int main(int argc, char* argv[])
{
int i;
ThreadArgs threadArgs[MAX_THREADS];
int numThreadsRunning = 0;
memset(&ThreadArgs, 0, sizeof(ThreadArgs));
// Create 10 threads
printf("Creating %d threads\n", MAX_THREADS);
for (i = 0; i < MAX_THREADS; ++i)
{
printf("Thread number %d: ", i);
threadArgs[i].Id = i;
threadArgs[i].hTerminate = CreateEvent(NULL, TRUE, FALSE, NULL);
threadArgs[i].hThread = (HANDLE) _beginthreadex(NULL, 0, &ThreadFunc, &threadArgs[i], 0, &threadArgs[i].dwThreadId);
if (threadArgs[i].hThread != NULL)
{
printf("Created\n");
++numThreadsRunning;
}
else
printf("Not Created!\n");
}
printf("Threads running: %d\n", numThreadsRunning);
printf("To kill a thread (gracefully), press 0-%d, then <Enter>.\n", MAX_THREADS-1);
printf("Press any other key to exit.\n");
while (1)
{
int c = getc(stdin);
if (c == '\n')
continue;
if ((c < '0') || (c > '9'))
break;
int id = c - '0';
if (threadArgs[id].hThread != NULL)
{
printf ("Signaling Thread %d to Terminate\n", id);
SetEvent(threadArgs[id].hTerminate);
WaitForSingleObject(threadArgs[id].hThread, INFINITE);
DWORD exitCode = 0;
GetExitCodeThread(threadArgs[id].hThread, &exitCode);
CloseHandle(threadArgs[id].hThread);
threadArgs[id].hThread = NULL;
printf ("Thread %d Terminated. Exit Code: %u\n", id, exitCode);
--numThreadsRunning;
printf ("Threads still running: %d\n", numThreadsRunning);
}
else
printf ("Thread %d is not running\n", id);
}
if (numThreadsRunning > 0)
{
printf ("Signaling remaining Threads to Terminate\n");
HANDLE hThreads[MAX_THREADS];
DWORD numThreads = 0;
for (i = 0; i < MAX_THREADS; ++i)
{
if (threadArgs[i].hThread != NULL)
{
hThreads[numThreads] = threadArgs[i].hThread;
++numThreads;
SetEvent(threadArgs[i].hTerminate);
}
}
WaitForMultipleObjects(numThreads, hThreads, TRUE, INFINITE);
for (i = 0; i < MAX_THREADS; ++i)
{
if (hThreads[i].hThread)
CloseHandle(hThreads[i].hThread);
if (hThreads[i].hTerminate)
CloseHandle(hThreads[i].hTerminate);
}
printf ("Threads Terminated\n");
}
return 0;
}
答案 1 :(得分:0)
看看这篇msdn文章:
遍历主题列表
https://msdn.microsoft.com/en-us/library/windows/desktop/ms686852(v=vs.85).aspx
有关于如何列出进程线程的示例代码。
〜剪断
#include <windows.h>
#include <tlhelp32.h>
#include <tchar.h>
// Forward declarations:
BOOL ListProcessThreads( DWORD dwOwnerPID );
void printError( TCHAR* msg );
int main( void )
{
ListProcessThreads(GetCurrentProcessId() );
return 0;
}
BOOL ListProcessThreads( DWORD dwOwnerPID )
{
HANDLE hThreadSnap = INVALID_HANDLE_VALUE;
THREADENTRY32 te32;
// Take a snapshot of all running threads
hThreadSnap = CreateToolhelp32Snapshot( TH32CS_SNAPTHREAD, 0 );
if( hThreadSnap == INVALID_HANDLE_VALUE )
return( FALSE );
// Fill in the size of the structure before using it.
te32.dwSize = sizeof(THREADENTRY32 );
// Retrieve information about the first thread,
// and exit if unsuccessful
if( !Thread32First( hThreadSnap, &te32 ) )
{
printError( TEXT("Thread32First") ); // Show cause of failure
CloseHandle( hThreadSnap ); // Must clean up the snapshot object!
return( FALSE );
}
// Now walk the thread list of the system,
// and display information about each thread
// associated with the specified process
do
{
if( te32.th32OwnerProcessID == dwOwnerPID )
{
_tprintf( TEXT("\n THREAD ID = 0x%08X"), te32.th32ThreadID );
_tprintf( TEXT("\n base priority = %d"), te32.tpBasePri );
_tprintf( TEXT("\n delta priority = %d"), te32.tpDeltaPri );
}
} while( Thread32Next(hThreadSnap, &te32 ) );
_tprintf( TEXT("\n"));
// Don't forget to clean up the snapshot object.
CloseHandle( hThreadSnap );
return( TRUE );
}
void printError( TCHAR* msg )
{
DWORD eNum;
TCHAR sysMsg[256];
TCHAR* p;
eNum = GetLastError( );
FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, eNum,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
sysMsg, 256, NULL );
// Trim the end of the line and terminate it with a null
p = sysMsg;
while( ( *p > 31 ) || ( *p == 9 ) )
++p;
do { *p-- = 0; } while( ( p >= sysMsg ) &&
( ( *p == '.' ) || ( *p < 33 ) ) );
// Display the message
_tprintf( TEXT("\n WARNING: %s failed with error %d (%s)"), msg, eNum, sysMsg );
}