带有循环的程序不会用 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 杀死 您可能正在杀死 systemsleep 的调用而不是您自己的代码 - 使用适当的库调用进行睡眠而不是炮击,例如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 终止的主要内容,如果未能解决你的问题,请参考以下文章

linux自动启动程序用ctrl+c无法终止

WIN10中的Git Bash Ctrl C无法终止

Linux 上的 Ctrl+C 等终止信号或中断

如何使用 Ctrl-D 终止程序?

c语言高手请进,关于浮点型变量储存EOF字符的问题

C ++:终止遍历字符串向量的循环的最优雅方法?