我有一个程序要运行,直到用户按下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
之后终止?
答案 0 :(得分:85)
来自system()
的{{3}}(强调/大胆的):
system()
库函数使用documentation创建子进程 使用fork(2)执行命令中指定的shell命令 如下:命令完成后execl("/bin/sh", "sh", "-c", command, (char *) 0);
system()
返回。在执行命令期间,SIGCHLD将被阻止,并且在调用
system()
的过程中将忽略SIGINT和SIGQUIT(这些信号将根据其内部的默认值进行处理执行命令的子进程。
这解释了你的行为。
答案 1 :(得分:61)
我怀疑用户代码会运行一段时间,比如1 ms,而睡眠过程导致父进程阻塞100 ms,所以除非你对 CTRL + C非常持久键然后很可能忽略中断。
您应该使用适当的图书馆电话替换您对system("sleep .1")
的来电,例如改变:
system("sleep .1");
为:
usleep(100000); // NB: requires #include <unistd.h>
请参阅:man usleep。
答案 2 :(得分:2)
你试过捕捉信号吗?请参阅以下示例代码:
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()。