C语言 C 中的信号处理

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2485028/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 04:54:14  来源:igfitidea点击:

Signal Handling in C

cunixshellsignals

提问by Dave

How can I implement signal Handling for Ctrl-C and Ctrl-D in C....So If Ctrl-C is pressed then the program will ignore and try to get the input from the user again...If Ctrl-D is pressed then the program will terminate...

如何在 C 中实现 Ctrl-C 和 Ctrl-D 的信号处理....所以如果按下 Ctrl-C 那么程序将忽略并尝试再次从用户那里获取输入...如果 Ctrl-D 是按下然后程序将终止...

My program follows:

我的程序如下:

int main(){
 char msg[400];

 while(1){
   printf("Enter: ");
   fgets(msg,400,stdin);
   printf("%s\n",msg); 
 }
}

Thanks,

谢谢,

Dave

戴夫

回答by Tim Post

When dealing with POSIX signals, you have two means at your disposal. First, the easy (but deprecated) way, signal(). Second, the more elegant, current but complex way, sigaction(). Please use sigaction() unless you find that it isn't available on some platform that you need to work on.

在处理 POSIX 信号时,您可以使用两种方法。首先,简单(但已弃用)的方式,signal()。其次,更优雅、当前但复杂的方式是sigaction()。请使用 sigaction() ,除非您发现它在您需要工作的某些平台上不可用。

This chapterof the glibc manual explains differences between the two and gives good example code on how to use both. It also lists the signals that can be handled, recommends how they shouldbe handled and goes more in depth on how to tell how any given signal is (or is not) currently beinghandled. That's way more code than I'd want to paste into an answer here, hence the links.

glibc 手册的这一章解释了两者之间的区别,并提供了关于如何使用两者的很好的示例代码。它还列出了可以处理的信号,建议他们如何应该被处理,更在如何告诉任何给定的信号是如何(或没有)目前深度去处理。这比我想粘贴到这里的答案中的代码多得多,因此是链接。

It really is worth the hour or two it would take you to read the links and work through the examples. Signal handling (especially in programs that daemonize) is extremely important. A good program should handle all fatal signals that can be handled (i.e. SIGHUP) and explicitly ignore signals that it might not be using (i.e. SIGUSR1 / SIGUSR2).

花一两个小时阅读链接并完成示例确实值得。信号处理(尤其是在守护进程中)非常重要。一个好的程序应该处理所有可以处理的致命信号(即 SIGHUP)并明确忽略它可能不使用的信号(即 SIGUSR1 / SIGUSR2)。

It also won't hurt to study the difference between normal and real time signals, at least up to the understanding of how the kernel merges the prior and not the latter.

研究正常和实时信号之间的差异也无妨,至少要了解内核如何合并先验信号而不是后者。

Once you work through it, you'll probably feel inclined to write up an easy to modify set of functions to handle your signals and re-use that code over and over again.

一旦您完成了它,您可能会倾向于编写一组易于修改的函数来处理您的信号并一遍又一遍地重用该代码。

Sorry for not giving a quick and dirty code snippet to show you how to solve your immediate need, but this isn't a quick and dirty topic :)

很抱歉没有给出一个快速而肮脏的代码片段来向您展示如何解决您的紧迫需求,但这不是一个快速而肮脏的话题:)

回答by t0mm13b

Firstly, Ctrl+D is an EOF indicator which you cannot trap, when a program is waiting for input, hitting Ctrl+D signifies end of file and to expect no more input. On the other hand, using Ctrl+C to terminate a program - that is SIGINT, which can be trapped by doing this:

首先,Ctrl+D 是一个 EOF 指示符,您无法捕获它,当程序正在等待输入时,按 Ctrl+D 表示文件结束并且不会再有输入。另一方面,使用 Ctrl+C 终止程序 - 即 SIGINT,可以通过执行以下操作来捕获它:

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

static void signal_handler(int);
static void cleanup(void);
void init_signals(void);
void panic(const char *, ...);

struct sigaction sigact;
char *progname;

int main(int argc, char **argv){
    char *s;
    progname = *(argv);
    atexit(cleanup);
    init_signals();
    // do the work
    exit(0);
}

void init_signals(void){
    sigact.sa_handler = signal_handler;
    sigemptyset(&sigact.sa_mask);
    sigact.sa_flags = 0;
    sigaction(SIGINT, &sigact, (struct sigaction *)NULL);
}

static void signal_handler(int sig){
    if (sig == SIGINT) panic("Caught signal for Ctrl+C\n");
}

void panic(const char *fmt, ...){
    char buf[50];
    va_list argptr;
    va_start(argptr, fmt);
    vsprintf(buf, fmt, argptr);
    va_end(argptr);
    fprintf(stderr, buf);
    exit(-1);
}

void cleanup(void){
    sigemptyset(&sigact.sa_mask);
    /* Do any cleaning up chores here */
}

回答by Giuseppe Guerrini

In your example it seems you don't need CTRL-C handlind at all. A "signal(SIGINT,SIG_IGN)" seems enough for you, unless your application must handle a SIGINT coming from some other source. CTRL-D doesn't usually generates signals, it simply communicates the EOF condition. You can in general control the behavior of your terminal (we are talking about console input, it isn't?) by using the termios library(also here). You can enable, redefine or disable the "interrupt" character (CTRL-C), the EOF one and many other ones (XON, XOFF, modem control...)

在您的示例中,您似乎根本不需要 CTRL-C 处理程序。“信号(SIGINT,SIG_IGN)”对您来说似乎就足够了,除非您的应用程序必须处理来自其他来源的 SIGINT。CTRL-D 通常不生成信号,它只是传达 EOF 条件。您通常可以通过使用termios 库(也在这里)来控制终端的行为(我们说的是控制台输入,不是吗?)。您可以启用、重新定义或禁用“中断”字符 (CTRL-C)、EOF 和许多其他字符(XON、XOFF、调制解调器控制...)

Regards

问候

回答by RUSHIKESH KARDE

This is a program for handling signal when pressed Ctrl+c

这是一个按 Ctrl+c 时处理信号的程序

The syntax for signal function is : signal(signal name, function name);

信号函数的语法是: signal(signal name, function name);

#include<stdio.h>
#include<signal.h>  // for handling signal 

void signal_handler() 
{
    printf("Signal Handled here\n");
}

main() 
{
    printf("In main function..\n");

    // SIGINT is signal name create  when Ctrl+c will pressed 
    signal(SIGINT,signal_handler);  

    sleep(15);

    printf("In main after called from signal_handle \n");

}

回答by Sherlock

#include<signal.h>
#include<unistd.h>
#include<stdio.h>
void signal_catch()
{
    printf("hi,Your signal catched Here");  
}
int main()
{
    signal(SIGINT,signal_catch);
//press ctrl+c
    sleep(10);
    return 0;
}//end main

//if you want to simply ignore ctrl+c interrupt use following code in main

int main()
{
    signal(SIGINT,SIG_IGN);
    sleep(100);
    return 0;
}//end main  
//this program  wont accept ctrl+c interrupt for 100 seconds.