代码之家  ›  专栏  ›  技术社区  ›  Jack

为什么关闭此应用程序?

  •  2
  • Jack  · 技术社区  · 2 年前

    处理信号是否会使应用程序关闭?我的目标是在时间用完但陷入循环时执行一些操作,直到找到用户输入q或EOF,但由于某种原因,一旦收到信号,应用程序似乎根本不执行循环,只打印printf(“从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;
    }
    
    1 回复  |  直到 2 年前
        1
  •  2
  •   dbush    2 年前

    信号处理程序在 getchar 正在等待用户输入。

    在信号处理器返回之后, getchar 返回EOF和 errno 设置为 EINTR ,表示呼叫被中断。这将导致循环退出。

        2
  •  2
  •   Harith    2 年前

    如果发生读取错误,则错误 应设置流的指示符,getchar()应返回EOF, 并应设置errno以指示错误。

    这个 getchar() 如果需要读取数据并且:

    EINTR

    由于收到 信号,并且没有传输任何数据。

    信号处理程序完成后,执行返回到信号中断它的位置。 getchar() 然后返回 EOF 因为它被一个信号中断,并设置 errno EINTR ,导致 while 循环退出。

    也就是说,您的代码只是调用未定义的行为,因为 printf() 是异步信号不安全的,即不能在信号处理程序中安全地调用它。(既不在C标准中,也不在POSIX标准中)。

    尽管如此,POSIX标准确实定义了 write() syscall是异步信号安全的,可以用来代替 打印() :

    write (STDOUT_FILENO, "time run out!!!\n", 17);