【问题标题】:Closing thread using ExitThread - C使用 ExitThread 关闭线程 - C
【发布时间】:2011-01-29 11:18:33
【问题描述】:

我有一个简单的程序,它创建一个线程,循环二十次,然后调用关闭自身并执行必要的清理。

当我调试程序时,它到达了 ExitThread();方法并暂停,忽略 printf();我已经在它之后设置了向我发出它已关闭的信号。

这是正常的还是我忘记做某事?我是使用 C 线程的新手。

Main()

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 可以让程序正常运行。

感谢大家的意见。

【问题讨论】:

  • 您的循环(就在 StartTimer 之后)没有在您创建的线程上运行;它在主线程上运行。那是你的意图吗? ThreadFunc 指向的任何方法都将在线程上运行
  • 我想我自己搞糊涂了,我的目的是创建一个线程,执行一个操作20次,然后在完全关闭程序之前退出线程。
  • 是的,这不是你在做的事情,你要做的是从 ThreadFunc 的入口点启动线程,然后在 threadfunc 中执行任务。

标签: c winapi multithreading


【解决方案1】:

是的,这是“正常的”,通过调用 ExitThread,你告诉 Windows 你已经完成了那个调用线程,所以其余的代码不会被调用。有点像调用exit(0)。

我个人不会这样使用它。剩下的代码没问题,你在清理线程,正常退出你的线程函数就好了。

【讨论】:

    【解决方案2】:

    正常,因为ExitThread实际上退出了当前线程,所以永远不会返回,也永远不会执行后面的指令。

    顺便说一句,你不应该直接调用 ExitThread(除非你真的知道你在做什么):你只需要从线程函数中返回。

    那么,如果您使用 C 运行时库,则不应使用原始线程 API,而应使用 C 运行时库函数,如 _beginthread 和 _beginthreadex。

    【讨论】:

    • 感谢您的澄清
    【解决方案3】:

    ExittThread 函数立即终止 CALLING 线程。

    【讨论】:

      【解决方案4】:

      由于您是在主线程的上下文中调用 StopTimer,所以当它调用退出线程时,它会结束主线程并随之结束进程。

      【讨论】:

      • 感谢杰的帮助
      【解决方案5】:

      你可以在ThreadFunc的开始处创建一个Event,比如hStop,并且在每个循环中不等待这个事件。然后你可以在主线程中使用 SetEvent() 请求线程停止。

      注意对于与 LIBCMT.LIB 链接的可执行文件,不要调用 Win32 ExitThread API;这可以防止运行时系统回收分配的资源。 _endthread 和_endthreadex 回收分配的线程资源,然后调用ExitThread。

      【讨论】:

        猜你喜欢
        • 2021-11-01
        • 1970-01-01
        • 1970-01-01
        • 2013-10-03
        • 2011-04-28
        • 2010-09-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多