简体   繁体   English

在C中使用信号处理函数后,如何避免scanf?

[英]How to avoid scanf after my signal handler function in C?

I have this code: 我有以下代码:

#include <stdio.h>
#include <signal.h>
void signal_handler(int signal) {
    printf("Caught signal in CHILD.\n");
}

int main(void) {
    int s;
    signal(SIGTSTP, signal_handler);
    while(1){
         printf("%s@%s/# ",getlogin(),get_current_dir_name());
         scanf("%d",&s);
    }
    return 0;
}

when i run the code it prints: 当我运行代码时,它会打印:

something: ^ZCaught signal in CHILD.

As far i understand that the scanf doesn't execute when i press the ctr-z. 据我了解,当我按下ctr-z时scanf不会执行。 Although after the printf inside my function it goes straight to the scanf, waits for input and then starts the loop again.Is there any way to avoid scanf when i press ctr-z and start the while loop again? 虽然在函数中执行printf之后,它会直接进入scanf,等待输入然后再次启动循环。当我按ctr-z并再次启动while循环时,有什么办法可以避免scanf? I tried something like that 我尝试过这样的事情

void signal_handler(int signal) {
    printf("Caught signal in CHILD.\n");
    printf("%s@%s/# ",getlogin(),get_current_dir_name());
}

but it didn't work. 但这没用。 After the second printf goes straight to the scanf, waits for input and then starts the loop again. 在第二个printf直接进入scanf之后,等待输入,然后再次开始循环。 Can i, somehow, start the loop again? 我可以以某种方式再次开始循环吗?

The signal handler is interrupting scanf during its read of STDIN. read STDIN期间,信号处理程序正在中断scanf However, because of the way you set signal disposition, the read system call restarts immediately upon return of the signal handler. 但是,由于设置信号处理方式的原因, read系统调用将在信号处理程序返回时立即重新启动。 That's why you are "stuck" in the scanf rather than back at the top of your loop. 这就是为什么您“卡在” scanf而不是回到循环的顶部。

One important thing you can do is to use sigaction rather than signal . 您可以做的重要一件事是使用sigaction而不是signal This will force you to specify the behavior of interrupted calls: restart them or not? 这将迫使您指定中断呼叫的行为:是否重新启动它们?

The next thing to do is to limit your signal handlers to functions that are async-signal-safe , lest you risk misery . 接下来要做的是将信号处理程序限制为异步信号安全的函数,以免遭受痛苦

As an aside, another change to make is to give us all the required includes ( <unistd.h> ?) and defines ( _GNU_SOURCE ?) to make your program work. _GNU_SOURCE ,要进行的另一项更改是为我们提供所有必需的包含( <unistd.h> ?)并定义( _GNU_SOURCE ?)以使您的程序正常工作。

As commented the worst solution should be: 如所评论,最糟糕的解决方案应该是:

#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <stdlib.h>

void signal_handler(int signal) {
    printf("Caught signal in CHILD.\n");
    exit(1);

}

int main(void) {
    int s;
    signal(SIGTSTP, signal_handler);
    while(1){
         printf("test\n");
         scanf("%d",&s);
    }
    return 0;
}

Better solution 更好的解决方案

#include <stdio.h>
#include <signal.h>

static volatile int keepRunning = 1;

void signal_handler(int signal) {
    printf("Caught signal in CHILD.\n");
    keepRunning = 0;

}

int main(void) {
    int s;
    signal(SIGTSTP, signal_handler);
    while(keepRunning){
         printf("test\n");
         scanf("%d",&s);
    }
    return 0;
}

EDIT after comments 评论后编辑

#include <stdio.h>
#include <signal.h>

static volatile int skipPrintf= 1;

void signal_handler(int signal) {
    printf("Caught signal in CHILD.\n");
    skipPrintf= 1;

}

int main(void) {
    int s;
    signal(SIGTSTP, signal_handler);
    while(1){
         if (skipPrintf == 0)
         {
             printf("test\n");
         }
         else
         {
             skipPrintf = 0;
         }
         scanf("%d",&s);
    }
    return 0;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM