【问题标题】:What's the proper way to cleanup an infinite loop application in Linux?在 Linux 中清理无限循环应用程序的正确方法是什么?
【发布时间】:2013-04-01 14:26:30
【问题描述】:

我主要来自 Windows 环境,所以在过渡到在 Linux 中编写一些东西时我有点迷茫。

假设我有一个简单的 C/C++ 应用程序,如下所示:

int main(int argc, char** argv)
{
    int h = open("something");

    while (true)
    {
        // do work
        usleep(10000);
    }

    close(h);
}

在 Windows 中,我会使用类似GetAsyncKeyState()(或某种其他类型的键盘检查功能)来查找转义键,并在按下它时跳出我的循环。这样我的close(h) 就会被调用,我会做所有我需要做的清理工作。

我在 Linux 中终止我的应用程序的方式一直是使用 CTRL+C,从我的阅读来看,这意味着它发送 SIGINT,并且是一个 '友好的方式来导致应用程序退出。然而,根据我的经验,这只是导致它在收到该信号时丢弃所有内容并关闭它(这意味着我的循环后清理永远不会运行。)

有些人建议我使用signal() 来收听SIGINT,但其他人不同意这种方法。 (另外,它往往会在 Windows 和 Linux 之间的操作方式上产生更多差异,我希望尽可能地在这两个平台上运行。)

这样的事情有“最佳实践”吗?

【问题讨论】:

  • 当一个进程存在时,所有句柄都会自动关闭。如果这是您唯一的清理原因,那么依靠 ctrl-c 是完全有效的。
  • 阅读 advancedlinuxprogramming.comintro(2) 手册页。另请阅读有关多路复用系统调用的信息,例如 poll(2)

标签: c++ c linux windows cross-platform


【解决方案1】:

使用SIGINT 处理程序实际上是在 POSIX 世界中处理这些事情的正常方式,类似于在 Windows 中使用 SetConsoleCtrlHandler

SIGINT 信号处理程序中,您设置一个标志,循环检查该标志是否应该退出。

但是,它不是严格需要的,除非您在清理中有特殊需要(例如向其他应用程序发送再见消息或类似的信息)。操作系统将确保正确关闭所有文件,释放所有内存分配等。就像在 Windows 中一样。

【讨论】:

    【解决方案2】:

    SIGINT 的默认动作是以正常方式终止程序。当程序以这种方式退出时,所有打开的文件都会自动关闭,所以close没有显式运行也没关系。

    当然可以设置一个信号处理程序来关闭程序,但对于这样的事情,它会是矫枉过正。通常,如果您按 ctrl-c 退出程序,您会期待一个非常快速的终止。

    如果您打开了多个已写入的文件,并且它们都需要处于相对于彼此一致的状态,您可能需要处理信号。

    【讨论】:

    • 我也喜欢你回答中的解释,但我只能将一个标记为答案,而 Joachim 只是稍微击败了你。非常感谢,teppic!
    • @nitz - 别担心!
    【解决方案3】:

    通常当你执行 getch();您的程序的输入被阻止,直到一个键被击中。这在 unix 世界中称为“规范”处理(canons=rules)。你可以把它关掉。因此,当您执行 getch();并且没有按下任何键,它会立即返回 -1 或任何类型的错误代码。

    我已经 15 年了,所以我不确定具体细节,但是,如果你用谷歌搜索 ioctl、termio、canonical、noncanonical,你会马上得到答案。

    但希望有人会好心地为您发布几行代码!抱歉,我只有一分钟的时间来回答。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-04
      • 1970-01-01
      相关资源
      最近更新 更多