如何安全终止多线程进程?

4
我正在处理一个项目,其中我们使用了pthread_create创建了几个子线程。 线程创建逻辑不在我的控制范围内,因为它是由项目的其他部分实现的。
每个线程执行一些需要超过30秒才能完成的操作。在正常情况下,程序可以正常运行。 但是,在程序终止时会出现问题。当我收到SIGINT信号时,我需要尽快从主函数中退出。
当我调用exit()或从main函数返回时,将调用退出处理程序和全局对象的析构函数。我认为这些操作与运行中的线程存在竞争条件。而且我认为有许多竞争条件,这使得很难解决所有这些问题。我觉得有两种解决方法:
  1. 调用_exit()并忘记所有资源的释放
  2. 当收到SIGINT信号时,关闭/杀死所有线程,然后从主线程调用exit(),这将释放资源。
我认为第一种解决方法可行,但我不想突然终止进程。因此,我想知道是否有可能尽快终止所有子线程,以便退出处理程序和析构函数可以执行所需的清理任务并终止程序。
我已经阅读了这篇文章,请让我知道您是否了解其他方法:POSIX API调用以列出在进程中运行的所有pthread 此外,请让我知道是否还有其他解决方案。

这个能帮到你吗?链接 - IkarusDeveloper
1
你的程序必须根据定义了解任何给定时刻正在运行的可加入线程,并且不应关心根据定义无法加入的线程。因此,这个API调用将没有太大用处。 - n. m.
不要紧,一个无法安全关闭的进程,即使使用 _exit()SIGKILL 也是无法安全运行的。停电和硬件故障是生活中的事实,如果一个进程无法安全地处理这些问题,那么它就不够强大,不能被信任。如果您无法在任何时候使用 SIGKILL 关闭应用程序,那么您打算如何处理下一次停电、磁盘故障或 RAM 芯片失灵?希望它不会发生并不是一个计划。 - Andrew Henle
2个回答

2
在程序退出之前,你需要做什么呢?如果答案是“释放资源”,那么你就不需要担心了。如果你调用_exit,程序将立即退出,操作系统会为你清理一切。
另外要注意的是,在信号处理程序中可以安全执行的操作非常有限,因此不建议尝试自己进行任何清理工作。如果你感兴趣,可以在这里找到一个列表,列出了你可以做的事情。但是,例如不能将文件刷新到磁盘(这是我能想到的唯一一个你可能合法想要在此处执行的操作)。这是禁止的。

1
当我接收到SIGINT信号时,我需要尽可能快地从主函数中退出。这是如何定义的呢?因为没有办法像那样“尽可能快速地退出”,特别是只有一个这样的信号。 您可以设置标志,发布到信号量或类似的方式来设置状态,告诉其他线程是关闭时间,或者您可以杀死整个进程。 如果您选择设置标志或相似的方式来告诉其他线程关闭,您设置这些标志并从信号处理程序返回,并希望线程表现良好,进程干净地关闭。 如果您选择杀死线程,则杀死线程,杀死进程或调用_exit()实际上没有区别。您最好保持简单,直接调用_exit()。 当您在单个信号处理程序调用中必须做出决策时,这就是您可以在之间选择的所有内容。选一个。 更好的解决方案是使用逐步升级的信号。例如,当您获得SIGQUIT或SIGINT时,您将设置标志或以其他方式告诉线程清理并退出进程-否则。然后,五秒钟后,关闭进程的任何内容都会发送SIGTERM,"否则"就会发生。当您获得SIGTERM时,您的信号处理程序只需调用_exit()-这些线程有机会并且他们搞砸了,这是他们的错误。或者您可以调用abort()生成核心文件,可能提供足够的证据来修复不关闭的行为异常的线程。 最后,五秒钟后,管理进程将使用SIGKILL从轨道上摧毁该进程,以确保关闭。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接