Signal ()函数详细介绍 Linux函数

来源:互联网 发布:windows私有云 编辑:程序博客网 时间:2024/03/29 07:37

signal()函数理解

<signal.h> 这个头文件中。

signal(参数1,参数2);

参数1:我们要进行处理的信号。系统的信号我们可以再终端键入 kill -l查看(64)。其实这些信号时系统定义的宏。

参数2:我们处理的方式(是系统默认还是忽略还是捕获)。

一般有3中方式进行操作。

1eg: signal(SIGINT ,SIG_ING );

//SIG_ING 代表忽略SIGINT信号SIGINT信号代表由InterruptKey产生,通常是CTRL +C 或者是DELETE 。发送给所有ForeGround Group的进程。

下面我们写个死循环:

#include<stdio.h>#include<signal.h>int main(){    signal(SIGINT,SIG_IGN);    for(; ;);     return 0;}

这时我们保存执行。

按下CTRL _C程序没有反应。这就对了

如果我们想结束该程序可以按下CTRL +\来结束

其实当我们按下CTRL +\组合键时,是产生了SIGQUIT信号

2eg: signal(SIGINT ,SIG_DFL );

//SIGINT信号代表由InterruptKey产生,通常是CTRL +C或者是DELETE。发送给所有ForeGroundGroup的进程。 SIG_DFL代表执行系统默认操作,其实对于大多数信号的系统默认动作时终止该进程。这与不写此处理函数是一样的。

我们将上面的程序改成

#include<stdio.h>#include<signal.h>int main(){//    signal(SIGINT,SIG_IGN);    signal(SIGINT,SIG_DFL);    for(; ;);     return 0;}

这时就可以按下CTRL +C 来终止该进程了。把signal(SIGINT,SIG_DFL);这句去掉,效果是一样的。

(3) void ( *signal( int sig, void (* handler)( int )))( int );
int (*p)();
这是一个函数指针, p所指向的函数是一个不带任何参数, 并且返回值为int的一个函数.
int (*fun())();
这个式子与上面式子的区别在于用fun()代替了p,而fun()是一个函数,所以说就可以看成是fun()这个函数执行之后,它的返回值是一个函数指针,这个函数指针(其实就是上面的p)所指向的函数是一个不带任何参数,并且返回值为int的一个函数.

void (*signal(int signo, void (*handler)(int)))(int);就可以看成是signal()函数(它自己是带两个参数,一个为整型,一个为函数指针的函数),而这个signal()函数的返回值也为一个函数指针,这个函数指针指向一个带一个整型参数,并且返回值为void的一个函数.

在写信号处理函数时对于信号处理的函数也是void sig_fun(int signo);这种类型,恰好与上面signal()函数所返回的函数指针所指向的函数是一样的.void ( *signal() )( int );

signal是一个函数, 它返回一个函数指针, 后者所指向的函数接受一个整型参数 且没有返回值, 仔细看, 是不是siganal( int signo, void (*handler)(int) )的第2个参数了,对了,其实他所返回的就是 signal的第2个信号处理函数,指向信号处理函数,就可以执行函数了( signal内部时, signal把信号做为参数传递给handler信号处理函数,接着 signal函数返回指针, 并且又指向信号处理函数, 就开始执行它)

那么,signal函数的参数又是如何呢?signal函数接受两个参数:一个整型的信号编号,以及一个指向用户定义的信号处理函数的指针。我们此前已经定义了指向用户定义的信号处理函数的指针sfp:

void (*sfp)(int);

sfp 的类型可以通过将上面的声明中的sfp去掉而得到,即void (*)(int)。此外,signal函数的返回值是一个指向调用前的用户定义信号处理函数的指针,这个指针的类型与sfp指针类型一致。因此,我们可以如下声明signal函数:

void (*signal(int, void(*)(int)))(int);

同样地,使用typedef可以简化上面的函数声明:

typedef void (*HANDLER)(int);
HANDLER signal(int, HANDLER);

Ok;看个例子:

#include<stdio.h>#include<signal.h>typedef void(*signal_handler)(int);void signal_handler_fun(int signal_num){    printf("catch signal %d\n",signal_num);}int main(){    signal_handler p_signal=signal_handler_fun;//    signal(SIGINT,SIG_IGN);    signal(SIGINT,p_signal);    for(; ;);     return 0;}

此程序是对当我们按下CTRL +C键时,会执行我们定义的信号处理函数。

每当我们按下CTRL +C键时会打印该信号的number.可以看出该信号的num2

要想退出可以按下CTRL +\ 打印结果为最后一行。

一些常用的Signal 如下:

注:下面是从百度文库中找的(*^__^*) 嘻嘻……

SignalDescriptionSIGABRT由调用abort函数产生,进程非正常退出SIGALRM用alarm函数设置的timer超时或setitimer函数设置的interval timer超时SIGBUS某种特定的硬件异常,通常由内存访问引起SIGCANCEL由Solaris Thread Library内部使用,通常不会使用SIGCHLD进程Terminate或Stop的时候,SIGCHLD会发送给它的父进程。缺省情况下该Signal会被忽略SIGCONT当被stop的进程恢复运行的时候,自动发送SIGEMT和实现相关的硬件异常SIGFPE数学相关的异常,如被0除,浮点溢出,等等SIGFREEZESolaris专用,Hiberate或者Suspended时候发送SIGHUP发送给具有Terminal的Controlling Process,当terminal被disconnect时候发送SIGILL非法指令异常SIGINFOBSD signal。由Status Key产生,通常是CTRL+T。发送给所有Foreground Group的进程SIGINT由Interrupt Key产生,通常是CTRL+C或者DELETE。发送给所有ForeGround Group的进程SIGIO异步IO事件SIGIOT实现相关的硬件异常,一般对应SIGABRTSIGKILL无法处理和忽略。中止某个进程SIGLWP由Solaris Thread Libray内部使用SIGPIPE在reader中止之后写Pipe的时候发送SIGPOLL当某个事件发送给Pollable Device的时候发送SIGPROFSetitimer指定的Profiling Interval Timer所产生SIGPWR和系统相关。和UPS相关。SIGQUIT输入Quit Key的时候(CTRL+\)发送给所有Foreground Group的进程SIGSEGV非法内存访问SIGSTKFLTLinux专用,数学协处理器的栈异常SIGSTOP中止进程。无法处理和忽略。SIGSYS非法系统调用SIGTERM请求中止进程,kill命令缺省发送SIGTHAWSolaris专用,从Suspend恢复时候发送SIGTRAP实现相关的硬件异常。一般是调试异常SIGTSTPSuspend Key,一般是Ctrl+Z。发送给所有Foreground Group的进程SIGTTIN当Background Group的进程尝试读取Terminal的时候发送SIGTTOU当Background Group的进程尝试写Terminal的时候发送SIGURG当out-of-band data接收的时候可能发送SIGUSR1用户自定义signal 1SIGUSR2用户自定义signal 2SIGVTALRMsetitimer函数设置的Virtual Interval Timer超时的时候SIGWAITINGSolaris Thread Library内部实现专用SIGWINCH当Terminal的窗口大小改变的时候,发送给Foreground Group的所有进程SIGXCPU当CPU时间限制超时的时候SIGXFSZ进程超过文件大小限制SIGXRESSolaris专用,进程超过资源限制的时候发送
0 0