等待 C++ 静态对象中的线程
Wait for a thread inside a C++ static object
我有一个需要初始化成像的静态对象API。本次成像分配的资源API需要同线程释放
所以我在我的静态对象中启动一个线程来初始化所有内容,然后等待计数器达到零。发生这种情况时,线程将全部清理并完成。
这是托管库中的非托管 class,因此我无法使用 System::Threading::Thread(需要托管静态成员函数)或 std::thread(编译器错误,不受支持与 /clr).
所以我必须像这样开始我的话题:
CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&Initialize, this, 0, 0);
一切正常,初始化已完成,API 函数正常工作。但是当我关闭应用程序时,我看到我的静态对象的使用计数器达到零,但是线程从未调用清理函数,就好像线程被杀死了一样。有没有办法确保线程会一直存在并执行到结束?
我认为您可以通过以下两种方式之一进行:
将资源包装在 RAII-style 类 中,并重构使对象的生命周期位于您创建的线程的堆栈中,确保它们的析构函数在线程时被调用循环退出而不必调用任何额外的清理。如果当您的计数器达到 0 时线程正确返回没有问题,这应该是解决此问题的最简单和最干净的方法。
我认为您可以使用 window procedures 拦截 WM_CLOSE
消息,处理必要的清理然后继续传递消息,有效地“拖延”它直到您准备好关闭。请注意,即使您在 DLL 中,您仍然可以设置 window 过程和消息泵系统,您不需要 GUI 来执行此操作。但是,我不能 100% 确定您是否会收到与“拥有”您的 DLL 的应用程序有关的 WM_CLOSE
消息,我还没有尝试过。
但是,您必须在线程循环中通过 events 实现某种形式的消息传递,因为 WindowProc 将在不同的线程上调用,因此您知道何时调用清理过程。
我对 CLR 也不是很熟悉,因此与这些 API 交互可能有比原始 C++ 调用和句柄更简单的方法。
在以所有可能的方式解决这个问题并添加事件等之后,我想这是不可能的,所以我将不得不更改我的代码结构并将非托管 class 封装在托管 class,并将线程添加到托管class。
我有一个需要初始化成像的静态对象API。本次成像分配的资源API需要同线程释放
所以我在我的静态对象中启动一个线程来初始化所有内容,然后等待计数器达到零。发生这种情况时,线程将全部清理并完成。
这是托管库中的非托管 class,因此我无法使用 System::Threading::Thread(需要托管静态成员函数)或 std::thread(编译器错误,不受支持与 /clr).
所以我必须像这样开始我的话题:
CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&Initialize, this, 0, 0);
一切正常,初始化已完成,API 函数正常工作。但是当我关闭应用程序时,我看到我的静态对象的使用计数器达到零,但是线程从未调用清理函数,就好像线程被杀死了一样。有没有办法确保线程会一直存在并执行到结束?
我认为您可以通过以下两种方式之一进行:
将资源包装在 RAII-style 类 中,并重构使对象的生命周期位于您创建的线程的堆栈中,确保它们的析构函数在线程时被调用循环退出而不必调用任何额外的清理。如果当您的计数器达到 0 时线程正确返回没有问题,这应该是解决此问题的最简单和最干净的方法。
我认为您可以使用 window procedures 拦截
WM_CLOSE
消息,处理必要的清理然后继续传递消息,有效地“拖延”它直到您准备好关闭。请注意,即使您在 DLL 中,您仍然可以设置 window 过程和消息泵系统,您不需要 GUI 来执行此操作。但是,我不能 100% 确定您是否会收到与“拥有”您的 DLL 的应用程序有关的WM_CLOSE
消息,我还没有尝试过。
但是,您必须在线程循环中通过 events 实现某种形式的消息传递,因为 WindowProc 将在不同的线程上调用,因此您知道何时调用清理过程。
我对 CLR 也不是很熟悉,因此与这些 API 交互可能有比原始 C++ 调用和句柄更简单的方法。
在以所有可能的方式解决这个问题并添加事件等之后,我想这是不可能的,所以我将不得不更改我的代码结构并将非托管 class 封装在托管 class,并将线程添加到托管class。