我有一个简单的程序创建一个线程,循环二十次,然后调用关闭自己并执行必要的清理。
当我调试程序时,它到达ExitThread();方法和暂停,忽略printf();我已经建立了它,向我发出信号已经关闭。
这是正常还是我忘了做某事?我是使用C进行线程化的新手。
主要()
void main()
{
Time t;
int i = 0;
StartTimer();
for(i = 0; i < 20; i++)
{
t = GetTime();
printf("%d.%.3d\n", t.seconds, t.milliseconds);
Sleep(100);
}
StopTimer();
}
线程创建
void StartTimer()
{
DWORD threadId;
seconds = 0;
milliseconds = 0;
// Create child thread
hThread = CreateThread(
NULL, // lpThreadAttributes (default)
0, // dwStackSize (default)
ThreadFunc, // lpStartAddress
NULL, // lpParameter
0, // dwCreationFlags
&threadId // lpThreadId (returned by function)
);
// Check child thread was created successfully
if(hThread == NULL)
{
printf("Error creating thread\n");
}
}
关闭主题
void StopTimer()
{
DWORD exitCode;
if(GetExitCodeThread(hThread,&exitCode) != 0)
{
ExitThread(exitCode);
printf("Thread closed");
if(CloseHandle(hThread))
{
printf("Handle closed");
}
}
}
修改
我已经意识到ExitThread()会停止执行的线程,因此我尝试使用不同的方法来停止计时器,但我仍然留下相同的结果。
void StopTimer()
{
WaitForSingleObject(hThread,INFINITE);
}
解决方案:
程序在WaitForSingleObject()调用时停止的原因并且无论进程多长时间都是因为它正在等待的操作有一个无限循环。
它将等待无限循环完成,而不是最好的事情。将WaitForSingleObject()的延迟更改为更合理的延迟,例如100允许程序正常运行。
感谢您的所有输入。
答案 0 :(得分:2)
是的,这是“正常的”,通过调用ExitThread,你告诉Windows你已经完成了调用线程,所以其余的代码不会被调用。这有点像调用exit(0)。
就我个人而言,我不会这样使用它。其余代码没问题,你正在清理线程,只需正常退出线程函数。
答案 1 :(得分:1)
这是正常的,因为ExitThread实际上退出当前线程,所以它永远不会返回,并且永远不会执行以下指令。
顺便说一下,你永远不应该直接调用ExitThread(除非你真的知道你在做什么):你只需要从线程函数返回。
然后,如果您使用C运行时库,则不应使用原始线程API,但C运行时库的功能类似于_beginthread和_beginthreadex。
答案 2 :(得分:1)
ExittThread函数立即终止CALLING线程。
答案 3 :(得分:1)
由于你在主线程的上下文中调用StopTimer,当它调用exit线程时,它会结束主线程并随之结束它终止进程。
答案 4 :(得分:0)
您可以在ThreadFunc的开头创建一个Event,例如hStop,并在每个循环中等待此事件。然后你可以在主线程中使用SetEvent()来让线程停止。
注意对于与LIBCMT.LIB链接的可执行文件,请不要调用Win32 ExitThread API;这可以防止运行时系统回收分配的资源。 _endthread and_endthreadex回收已分配的线程资源,然后调用ExitThread。