关于system("pause"),我知道它可以暂停命令行界面,等待用户的输入。但是对于以下代码,我遇到一些问题:
#include <iostream>
#include <csignal>
#include <Windows.h>
void controlCHandler(int signal)
{
std::cout << "Control-C detected..." << std::endl;
//exit(2);
//return;
system("pause");
}
int main()
{
signal(SIGINT, controlCHandler);
while (true) {
std::cout << "Sleeping..." << std::endl;
Sleep(1000);
}
return 0;
}
我的运行结果如下:
其中我按了三次Control-C才结束掉程序。难道pause命令不是把进程阻塞了么?为什么还能继续执行循环呢?这三次Control-C时各自发生了什么事情?
此外,我尝试对程序进行调试,发现在第一个和最后一个Control-C时,VS会报异常:
但中间一个并不会。这又是什么原因?
此外,换成return是按两次退出,用exit()直接退出程序是没有问题的,一次退出。
还望各位不吝赐教,感谢!如果需要环境方面的信息随时提出。
在C++中,system("pause")
调用确实会在命令行界面中暂停,并等待用户按任意键继续。然而,在你的特定情况下,system("pause")
被放在了一个信号处理函数 controlCHandler
中,这里有几个关键的问题点需要注意:
信号处理函数的限制:
controlCHandler
)应当尽可能简单和快速。在信号处理函数中调用像 system()
这样的复杂函数,可能会导致未定义行为,因为信号处理函数在执行时,程序的其他部分可能处于不确定的状态。system()
函数会启动一个新的进程来执行 pause
命令,这涉及到进程创建、执行、等待用户输入等复杂操作,这些操作在信号处理函数中执行可能不安全。循环继续执行的原因:
system("pause")
被调用时,它会暂停当前线程(如果 system()
是在多线程环境下被调用的话,否则就是整个进程),但它不会改变 controlCHandler
函数之后的执行流程。一旦用户按了任意键,pause
命令结束,system()
返回,controlCHandler
函数也随之结束。由于信号处理函数不会自动恢复或改变程序的其他部分(如循环),所以主循环会继续执行。异常的原因:
system("pause")
)与信号处理的上下文发生了冲突。第一次按 Control-C 触发了信号处理,但程序可能尚未准备好处理它(如某些资源尚未释放)。最后一次按 Control-C 时,程序可能已处于不稳定状态,因为已经多次尝试中断循环。system("pause")
后,程序状态在某种程度上被重置或稳定了,但这并不意味着这样做是安全的。关于 return
和 exit()
的行为:
return
会从 controlCHandler
函数返回,但并不会停止主循环。这是因为 return
只影响当前函数,而不是整个程序。exit(2);
会立即终止程序,并返回状态码 2 给操作系统。这是处理这类中断的一种更安全、更直接的方式。system()
:改用其他方式来处理中断,如设置标志位,然后在主循环中检查这个标志位以决定是否退出循环。exit()
:在信号处理函数中直接调用 exit()
来安全地终止程序。例如,修改你的 controlCHandler
函数如下:
void controlCHandler(int signal)
{
std::cout << "Control-C detected..." << std::endl;
exit(2); // 直接退出程序
}
这样,每次按 Control-C 时,程序都会立即退出,避免了潜在的不确定性和复杂性。
问题内容: 我应该如何从我的程序中运行另一个程序?我需要能够将数据写入启动的程序中(并可能从中读取) 我不确定这是否是标准的C函数。我需要应该在Linux下工作的解决方案。 问题答案: 您要使用。它为您提供了一个单向管道,您可以使用该管道访问程序的stdin和stdout。 popen是现代unix和类似unix的操作系统的标准配置,其中Linux是其中之一:-) 类型 在终端上阅读有关它的更多信
问题内容: 想知道是否有人知道一种在运行时从C#代码执行Java命令行程序的好方法吗? 它与执行本机.EXE文件相同吗? 它会同步还是异步运行(这意味着我可能必须等待线程完成才能找到结果) 具体来说,我想从服务器端的Web应用程序中调用一个小工具(恰好用Java编写),以对文本文件进行一些处理。我想等待它完成,因为在Java程序完成对文本文件的处理之后,我想获取处理后的文本,并在C#应用程序中使用
问题内容: 我正在阅读有关章节的内容。似乎您可以按以下方式列出节和段之间的映射。 我的问题, 我不明白程序头是什么意思?它们与细分有何关系? 段到段的映射很清楚。但是有人可以命名吗?我只看到数字。我确定了代码段(03),数据段(02)和堆栈(07)。 问题答案: 了解它的输出将帮助您了解文件的格式。请参考本文件。 就了解如何解释此链接的输出而言可能会有帮助。 关于您的问题2,此链接描述了细分。在该
问题内容: 我有一棵divs树: 在div上单击时,将使其子级不可见-即单击“ a”将使“ b”和“ c”不可见。 问题是:单击“ b”将调用“ a”的单击,并使“ b”和“ c”不可见。如何使用jQuery禁用对“ a”的点击? 谢谢 问题答案: 您可以为孩子添加一个处理程序,以防止click事件蔓延: 这样一来,点击不会传播到。都不会单击以转到,因此也不会。
本文向大家介绍C#实现终止正在执行的线程,包括了C#实现终止正在执行的线程的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了C#实现终止正在执行的线程的实现方法,并针对一些容易出错的地方进行了深入分析,具体方法如下: 一般来说,很多人都会使用Abort方法来终止线程,其实这种做法并不可取!如果你的线程正在操作临界资源,很有可能会造成资源没有正确释放而出现死锁问题。正确的做法应该是使用标记来终
问题内容: 看完管道和Jenkinsfile文档后,我对如何创建 _舞台- >生产_管道感到困惑。 一种方法是使用类似 这似乎有点笨拙,因为这将一直阻塞执行程序,直到您要部署到生产环境为止。Jenkins是否有其他任何可以部署到生产环境的方法。 问题答案: 编辑(2016年10月):请参阅下面的其他答案“使用里程碑并锁定”,其中包括最近引入的功能。 作为第一个选择,您可以将您的步骤包装为一个步骤。