c++ - TerminateThread 中的无效句柄错误

标签 c++ winapi signals

我有一个应用程序,它通过 SetConsoleCtrlHandler 注册了句柄例程。事情是中断信号我必须在退出前做一些清理,这就是问题开始的时候。因为,其他线程继续运行并使用一些应该释放的资源,我在清理期间遇到了访问冲突。我试图保存正在使用这些资源的线程实例并在调用清理例程之前停止它们,但这没有帮助。我经常收到 ERROR_INVALID_HANDLE。我尝试通过 DuplicateHandle 获取线程实例,我还尝试仅保存线程 ID,然后通过 OpenThread 函数获取线程句柄。但仍然显示无效句柄错误。

此外,当我枚举所有线程实例并尝试终止它们时,我得到了同样的错误。在我看来,句柄例程周围有一些“魔法”,不允许从中终止其他线程。

枚举所有线程的列表

HANDLE h = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
                    if (h != INVALID_HANDLE_VALUE) {
                        THREADENTRY32 te;
                        te.dwSize = sizeof(te);
                        if (Thread32First(h, &te)) {
                            do {
                                if (te.dwSize >= FIELD_OFFSET(THREADENTRY32, th32OwnerProcessID) +
                                    sizeof(te.th32OwnerProcessID)) {
 HANDLE thread = OpenThread(THREAD_TERMINATE, FALSE, te.th32ThreadID);
                                        if (TerminateThread(thread , NUM_SIG_ACTION_1) == 0)
                                        {
  //                                          printf("terminate failed (%d)\n", GetLastError());
                                            if( SuspendThread(thread ) == -1)
                                            {
//                                                printf("suspend failed (%d)\n", GetLastError());
                                            }
                                        }
                                }
                                te.dwSize = sizeof(te);
                            } while (Thread32Next(h, &te));
                        }
                        CloseHandle(h);
                    }

通过 DuplicateHandle 获取线程列表

//code in working thread
DuplicateHandle(GetCurrentProcess(), GetCurrentThread(), GetCurrentProcess(), &g_hWorkerThread ,
                             DUPLICATE_SAME_ACCESS, FALSE, DUPLICATE_SAME_ACCESS);
//code in handler routine

                if (TerminateThread( g_hWorkerThread , NUM_SIG_ACTION_1 ) == 0)
                {
                    printf("Terminate thread failed (%d)\n", GetLastError());
                }

OpenThread 列表

//code from worker thread
g_iWorkerThreadId = GetThreadId(GetCurrentThread());
//code in routine handler
HANDLE handle = OpenThread(THREAD_TERMINATE, FALSE, g_iWorkerThreadId); 
                   if (TerminateThread( handle , NUM_SIG_ACTION_1 ) == 0)
                    {
                        printf("Terminate thread failed (%d)\n", GetLastError());
                    }

有没有强制处理例程运行到当前工作线程?

我们将不胜感激。

提前致谢。

最佳答案

您正在尝试自己做一些操作系统已经在做的事情。不要与系统作对。 让我建议另一种工作方式,它可以大大简化您的代码。

当您的主应用程序线程收到 Ctrl 信号时,它想要关闭该应用程序。 您可以让 Windows 为您执行此操作,但您可能会使资源处于未定义状态,因此这就是您希望正常关闭的原因。

很可能,每个线程都已经运行了一个事件循环——这是基本的 Windows 应用程序范例。根据 ctrl 信号,将事件发布到您的其他线程并在每个线程的事件循环中捕获它们。添加自定义事件代码,使它们能够优雅地自行结束。您现在只需等待所有线程句柄以确保所有线程都已结束。

使用TerminateThread 不是一个好主意,它与线程的优雅结束恰恰相反。

关于c++ - TerminateThread 中的无效句柄错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23889541/

相关文章:

C++ 接口(interface)、继承、多态性

c - 为什么 WIFSIGNALED(status) 在使用 ptrace 跟踪进程时无法检测到信号?

c++ - Qt Creator 中缺少编译器

c++ - 用于插入操作的二叉搜索树代码问题

c++ - 录制应用程序的音频输出

c++ - 枚举注册表项 C++

c - 在循环中使用 scanf 处理 SIGINT

postgresql - 如何捕获客户端信号并在后端终止 postgresql 查询?

c++ - 如何避免 "dynamic initialization in unreachable code"警告?

C linux相当于windows QueryPerformanceCounter