如何安全终止多线程进程

How to safely terminate a multithreaded process

我正在开发一个项目,我们使用 pthread_create 创建了多个子线程。 线程创建逻辑不受我控制,因为它由项目的其他部分实现。

每个线程执行一些需要超过 30 秒才能完成的操作。 在正常情况下,该程序运行良好。 但是问题出现在程序终止的时候。 当我收到 SIGINT 信号时,我需要尽快退出 main。

当我从 main 调用 exit() 或 return 时,将调用退出处理程序和全局对象的析构函数。而且我相信这些操作与 运行 线程存在竞争条件。而且我相信有很多竞争条件,这很难解决所有这些问题。 在我看来,有两种解决方案。

  1. 调用 _exit() 并忘记所有资源的取消分配
  2. 当SIGINT存在时,close/kill所有线程然后从主线程调用exit(),释放资源。

我认为第一个选项可行,但我不想突然终止进程。 所以我想知道是否有可能尽快终止所有子线程,以便退出处理程序和析构函数可以执行所需的清理任务并终止程序。

我已经完成了这个 post,如果您知道其他方法,请告诉我:POSIX API call to list all the pthreads running in a process

此外,如果有任何其他解决方案可以解决此问题,请告诉我

程序退出前需要做什么?如果答案是'deallocate resources',那你就不用担心了。如果你调用 _exit 那么程序会立即退出并且 OS 会为你清理一切。

另请注意,您可以在信号处理程序中安全地执行的操作非常有限,因此不建议您尝试自行执行任何清理工作。如果您有兴趣,可以查看可以 可以here 执行的操作列表。但是,例如,您不能将文件刷新到磁盘(这是我能想到的您可能合法想在这里做的唯一事情)。那是禁区。

I need to exit from main as quickly as possible when I receive the SIGINT signal.

这是怎么定义的?因为当你收到这样的信号时,没有办法“尽快退出”。

您可以设置标志,post 到信号量,或类似设置一个状态来告诉其他线程是时候关闭了,或者您可以终止整个进程。

如果您选择设置标志或类似的标志来告诉其他线程关闭,您可以从信号处理程序中设置这些标志和 return,并希望线程正常运行并且进程干净地关闭.

如果您选择终止线程,则终止线程、终止进程或调用 _exit() 实际上没有区别。您不妨保持简单并调用 _exit().

当您必须在单个信号处理程序调用中做出决定时,您可以选择的就这些。选一个。

更好的解决方案是使用升级信号。例如,当您获得 SIGQUITSIGINT 时,您设置标志或以其他方式告诉线程是时候清理并退出进程了 - 或其他 .然后,说五秒钟后关闭您的进程的任何内容都会发送 SIGTERM 并且“否则”会发生。当您得到 SIGTERM 时,您的信号处理程序只需调用 _exit() - 那些线程有他们的机会,但他们搞砸了,那是 他们的错 。或者您可以调用 abort() 生成一个核心文件,并可能提供足够的证据来修复不会关闭的恶意线程。

最后,五秒钟后,管理进程将从轨道上用 SIGKILL 核对进程以确保安全。