带有循环的程序不会用 CTRL + C 终止
Posted
技术标签:
【中文标题】带有循环的程序不会用 CTRL + C 终止【英文标题】:Program with loop will not terminate with CTRL + C 【发布时间】:2014-10-19 13:26:45 【问题描述】:我有一个程序要运行,直到被用户按 CTRL + C 中断。当我按下它时,什么也没有发生,我只能通过暂停程序并在此之后手动终止它来终止程序。
这是需要无限运行的代码部分:
while(true)
liveOrDie(field);
printOut(field);
第一个函数计算是否将 1 或 0 放入二维数组,第二个函数使用 for 循环将其打印出来,如下所示:
void printOut(int field[38][102])
for(int i = 0; i < 38; i++)
for(int j = 0; j < 102; j++)
if(field[i][j] == 1)
cout << "o";
else
cout << " ";
cout << endl;
system("sleep .1");
使用睡眠,以便在清除之前有足够的时间在屏幕上打印所有内容。
因此,程序不会以Ctrl+C
终止。什么可能导致这种行为,以及如何使程序在Ctrl+C
之后终止?
【问题讨论】:
尝试使用 CTRL+Z 杀死 您可能正在杀死system
对 sleep
的调用而不是您自己的代码 - 使用适当的库调用进行睡眠而不是炮击,例如sleep(1)
.
这是人生游戏吗?
是的,这是生命游戏。
【参考方案1】:
来自system()
的documentation(强调/粗体):
system()
库函数使用fork(2) 创建子进程 使用execl(3)执行命令中指定的shell命令 如下:execl("/bin/sh", "sh", "-c", command, (char *) 0);
system()
在命令完成后返回。在命令执行过程中,SIGCHLD会被阻塞,SIGINT和SIGQUIT会被忽略,在调用
system()
的进程中(这些信号会在子进程内部按照它们的默认值进行处理)执行命令的进程)。
这解释了你的行为。
【讨论】:
+1 用于提供实际文档。另外,请不要使用 die.net,它已经过时了。 更新了文档。【参考方案2】:我怀疑用户代码运行了一小段时间,比如 1 毫秒,而睡眠进程导致父进程阻塞 100 毫秒,所以除非你非常坚持使用 CTRL + C 键,那么中断很可能会被忽略。
您应该将您对 system("sleep .1")
的调用替换为适当的库调用,例如改变:
system("sleep .1");
到:
usleep(100000); // NB: requires #include <unistd.h>
请参阅:man usleep。
【讨论】:
我认为命令usleep(1000)
也适用于人类 v2.0 以后【参考方案3】:
您是否尝试过捕捉信号?请看下面的示例代码:
if (signal (SIGINT, yourFunctionHandler) == SIG_ERR)
cout << "Error setting the SIGINT handler";
void yourFunctionHandler (int signal)
cout << "Signal " << signal << " received!";
//do what's needed to kill loop
通过这种方式,您可以根据需要修改循环变量。正如其他人建议的那样,不要使用 system()。
Signal reference
Small tutorial
【讨论】:
问题是,system
很可能会覆盖您的信号处理程序(无论是默认的还是您自己的)。
这就是为什么我添加了 don't use system() :-)以上是关于带有循环的程序不会用 CTRL + C 终止的主要内容,如果未能解决你的问题,请参考以下文章