为什么这个应用程序要关闭?

3
处理信号会导致应用程序关闭吗?我的目标是在时间耗尽时执行某些操作,但卡在循环中,直到用户输入q或找到EOF,但由于某种原因,一旦接收到信号,应用程序似乎根本不执行循环,只打印printf("returning from main!!\n");并退出应用程序。我错过了什么?我该如何解决?
以下是完整代码:
#include <signal.h>
#include <sys/time.h>
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <ucontext.h>
#include <unistd.h>

void thread_signal_handler(int signal)
{
    // Thread's time slice has run out, switch to another thread
    // ...
    printf("time run out!!!\n");
}

int main()
{
    // Set up the signal handler for the thread's time slice
    struct sigaction sa;
    sa.sa_handler = thread_signal_handler;
    sigemptyset(&sa.sa_mask);
    sa.sa_flags = 0;
    sigaction(SIGALRM, &sa, NULL);

    // Set up the timer for the thread's time slice
    struct itimerval timer;
    timer.it_value.tv_sec = 5;
    timer.it_value.tv_usec = 0;
    timer.it_interval.tv_sec = 0;
    timer.it_interval.tv_usec = 0;
    setitimer(ITIMER_REAL, &timer, NULL);

    while (1)
    {
        int ch = getchar();
        if(ch == 'q' || ch == EOF) break;
    }
    printf("returning from main!!\n");
    return 0;
}

2
在信号处理程序中调用 printf 是不安全的,即使它经常能够正常工作。 - user3386109
遗憾的是,setitimer已经过时了。您可以考虑使用代替方案timer_settime - pilcrow
2个回答

2
信号处理程序在getchar等待用户输入时被触发。
当信号处理程序返回后,getchar返回EOF,并将errno设置为EINTR,表示调用被中断。这导致您的循环退出。

2
如果发生读取错误,流的错误指示器将被设置,getchar()将返回EOF,并设置errno以指示错误。
如果需要读取数据,则getchar()函数将失败,原因如下:
EINTR
由于接收到信号而终止了读取操作,并且没有传输任何数据。
在信号处理程序完成后,执行将返回到信号中断它的点。然后,getchar()返回EOF,因为它被信号中断,并将errno设置为EINTR,这导致while循环退出。
话虽如此,您的代码仅会调用未定义的行为,因为printf()是异步信号不安全的,即不能在信号处理程序内安全地调用它(无论是C标准还是POSIX标准都是如此)。
尽管如此,POSIX标准确实定义了write()系统调用为异步信号安全,可以代替printf()使用:
write (STDOUT_FILENO, "time run out!!!\n", 17);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接