【问题标题】:Cast std::thread as HANDLE to call TerminateThread() [duplicate]将 std::thread 转换为 HANDLE 以调用 TerminateThread() [重复]
【发布时间】:2015-03-04 02:34:19
【问题描述】:

是否可以将 C++ 中的 std::thread 线程转换或转换为 Windows 中的 HANDLE? 我一直在尝试使用线程的 WINAPI 函数来管理 Windows 中的线程,但我无法让它工作......

#include <thread>
#include <string>
#include <iostream>
#include <windows.h>

void Hi(std::string n){
while(true){
    std::cout<<"Hi :3 "<<n<<"\n";
    std::this_thread::sleep_for(std::chrono::seconds(1));
}
}

int main(void){

std::thread first(Hi, "zoditu");

first.detach();
getc(stdin);

//SuspendThread((void*)first.native_handle());
TerminateThread((void*)first.native_handle(), (unsigned long)0x00);
CloseHandle((void*)first.native_handle());

std::cout<<"No D:!!\n";
getc(stdin);

return 0;
}

但似乎什么也没做,因为线程一直在控制台中产生“Hi's”......有没有办法使用 WINAPI “杀死”它?

【问题讨论】:

  • this 回答你的问题了吗?
  • @RonTang:我在问题中没有看到程序需要可移植的迹象。毕竟大多数都没有。
  • @JamesAdkison 不是真的,因为我没有要求线程 ID,因为我无法通过 WINAPI 中的 ID 获取线程。我在问如何将线程转换为 Windows HANDLE 以通过 Win32 中的 Thread 函数传递它。而且我不希望它可移植,我的问题是与 WINAPI 相关的大声笑:P
  • 当您调用first.detach() 时,您使first 忘记了线程句柄(以及有关线程的所有其他信息)。在调用detach()之前保存句柄,或者根本不调用detach()
  • 当然,调用 TerminateThread 是错误的做法。你需要的是优雅的终止。

标签: c++ windows multithreading winapi c++11


【解决方案1】:

我不认为将std::thread::native_handle()返回的值直接用于Win32 API函数有什么问题(即不需要转换)。

以下程序适合我。 然而,如果线程在主动执行时被终止,它通常(总是?)崩溃,但如果线程在终止之前被挂起,它就可以正常工作。正如您所知道的和其他人所指出的,终止线程通常不是一个好主意。

回答您的问题 Win32 API 似乎可以按预期工作而无需任何额外的转换。以下程序适用于我。

程序:

#include <windows.h>

#include <iostream>
#include <string>
#include <thread>

void foo()
{
    while (true)
    {
        std::cout << "foo()\n";
        std::this_thread::sleep_for(std::chrono::seconds(1));
    }
}

int main(void)
{
    std::thread first(foo);

    bool isFinished = false;
    while (!isFinished)
    {
        char ch = ::getchar();
        ::getchar(); // Swallow the new line character

        if (ch == 'e')
        {
            isFinished = true;
        }
        else if (ch == 's')
        {
            DWORD result = ::SuspendThread(first.native_handle());
            if (result != -1)
            {
                std::cout << "Successfully suspended thread\n";
            }
            else
            {
                std::cout << "Failed to suspend thread: failure resson " << ::GetLastError() << "\n";
            }
        }
        else if (ch == 'r')
        {
            DWORD result = ::ResumeThread(first.native_handle());
            if (result != -1)
            {
                std::cout << "Successfully resumed thread\n";
            }
            else
            {
                std::cout << "Failed to resume thread: failure resson " << ::GetLastError() << "\n";
            }
        }
        else if (ch == 'k')
        {
            DWORD result = ::TerminateThread(first.native_handle(), 1);
            if (result != 0)
            {
                std::cout << "Successfully terminated thread\n";
            }
            else
            {
                std::cout << "Failed to terminate thread: failure resson " << ::GetLastError() << "\n";
            }
        }
        else
        {
            std::cout << "Unhandled char '" << ch << "'\n";
        }
    }

    first.detach();

    std::cout << "waiting to exit main...";
    ::getchar();
    std::cout << "exiting...\n";

    return 0;
}

样本输出(我添加的cmets):

foo()
foo()
foo()
foo()
s
Successfully suspended thread // This was successful since 'foo()' is no longer printing
r
Successfully resumed thread // This was successful since 'foo()' is again printing
foo()
foo()
foo()
foo()
s
Successfully suspended thread // Worked again
k
Successfully terminated thread // Says it works...
r
Successfully resumed thread // Termination must have worked because resuming did not cause 'foo' to start printing
e
waiting to exit main...
exiting...

【讨论】:

  • 线程结束的原因是因为当getchar()接收到一个输入时,它会通过代码直到它到达return 0;,它完成了主线程,使它也完成了第一个线程。评论std::cout &lt;&lt; "Terminate? " &lt;&lt; (::TerminateThread(first.native_handle(), 1) ? "success" : "failure",你会发现结果是一样的。如果你在return 0; 之前添加getchar() 我会回到同样的问题......
  • @RamsesAsmush 我不确定我是否完全理解您的评论。但是,我在答案中更新了程序。据我所知,一切正常,无需任何额外的转换
猜你喜欢
  • 2012-06-15
  • 2013-05-11
  • 2013-09-10
  • 2012-10-31
  • 2014-09-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-07
相关资源
最近更新 更多