4

我主要来自 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 之间的工作方式之间产生更多差异,我希望尽可能地在两个平台上运行。)

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

4

3 回答 3

3

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

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

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

于 2013-04-01T14:32:14.157 回答
3

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

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

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

于 2013-04-01T14:33:45.293 回答
1

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

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

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

于 2013-04-01T14:40:23.900 回答