linux下的single()函数
使用signal()时的形式:signal(参数1, 参数2);#include#includeint main(){while(1){signal(SIGINT, SIG_IGN);printf("ctrl+c 失效!");}//for(; ;){}return 0;}头文件si'
·
使用signal()时的形式:
signal(参数1, 参数2);
头文件<signal.h>
其中参数1是我们要处理的信号,在linux命令行终端上输入kill-l可以查看这些信号,有64个,如下图:
参数2是我们根据参数1的信号做出的处理(一般有三种方式:系统默认,忽略, 捕获)。
下面我们看看这三种方式的具体事例和使用方法:
1.signal(SIGINT, SIG_IGN)
SIG_ING 代表忽略SIGINT信号,SIGINT信号代表由InterruptKey(中断密钥)产生,通常是CTRL +C 或者是DELETE 。发送给所有ForeGround Group(前台组)的进程。
我们都知道在linux下你运行程序后如果没有自动终止程序,我们通常是通过ctrl+c来让程序强制终止的,我们来改变这一方法,下面这个程序就可以让这种方法失效
实例一:我们来看一个死循环
#include<stdio.h>
#include<signal.h>
int main()
{
while(1)
{
signal(SIGINT, SIG_IGN);
printf("ctrl+c 失效!");
}
//for(; ;){}
return 0;
}
你可以通过ctrl+\或者ctrl+z来终止上述程序,其实作用都和ctrl+c差不多,有差别的只是这几个指令处理的信号不同罢了
2.signal(SIGINT, SIG_DFL)
这种是针对不同信号默认的interrup key,举例来说就像SIGINT对应ctrl+c一样,这种默认处理我们在程序中写不写没有什么影响,我们还是看一个例子:
实例二:
#include<stdio.h>
#include<signal.h>
int main()
{
while(1)
{
signal(SIGINT, SIG_DFL);
//signal(SIGINT, SIG_IGN);
printf("ctrl+c 失效!");
}
//for(; ;){}
return 0;
}
ctrl+c来终止程序
3.void ( *signal( int sig, void (* handler)( int )))( int );
首先我们要能看懂上面这个函数及其参数所表达的意思,这里涉及到c语言复杂声明的读写方式,自己查google吧,其中,我们看到signal这个函数有两个参数,一个整形,一个为函数指针的函数,这样讲下去不好理解,先来看个例子我们根据例子的具体内容来理解:
实例三:
#include <stdio.h> #include <signal.h> void sigintHandler(int sig_num) { signal(SIGINT, sigintHandler); printf("\n Cannot be terminated using Ctrl+C \n"); printf("%d", sig_num); fflush(stdout); } int main () { signal(SIGINT, sigintHandler); while(1) { } return 0; }
来看上面这个程序,在写信号处理函数时对于信号处理的函数也是void signalHandler(int sig_num);这种类型,恰好与上面signal()函数所返回的函数指针所指向的函数是一样的.void ( *signal() )( int );signal是一个函数, 它返回一个函数指针, 后者所指向的函数接受一个整型参数 且没有返回值, 仔细看, 是不是siganal( int sig, void (*handler)(int) )的第2个参数了,对了,其实他所返回的就是 signal的第2个信号处理函数,指向信号处理函数,就可以执行函数了( signal内部时, signal把信号做为参数传递给handler信号处理函数,接着 signal函数返回指针, 并且又指向信号处理函数, 就开始执行它)
反映到上面的程序通俗的讲就是void sigintHandler(int sig_num)的外形也和void (* handler)( int ))相同,所以上面这个程序其实是相当于我们自己写了signal()函数中的第二个参数
上面程序的运行结果为:
我们无法通过ctrl+c来终止程序
下面是一些常见的信号及其描述:
Signal | Description |
SIGABRT | 由调用abort函数产生,进程非正常退出 |
SIGALRM | 用alarm函数设置的timer超时或setitimer函数设置的interval timer超时 |
SIGBUS | 某种特定的硬件异常,通常由内存访问引起 |
SIGCANCEL | 由Solaris Thread Library内部使用,通常不会使用 |
SIGCHLD | 进程Terminate或Stop的时候,SIGCHLD会发送给它的父进程。缺省情况下该Signal会被忽略 |
SIGCONT | 当被stop的进程恢复运行的时候,自动发送 |
SIGEMT | 和实现相关的硬件异常 |
SIGFPE | 数学相关的异常,如被0除,浮点溢出,等等 |
SIGFREEZE | Solaris专用,Hiberate或者Suspended时候发送 |
SIGHUP | 发送给具有Terminal的Controlling Process,当terminal被disconnect时候发送 |
SIGILL | 非法指令异常 |
SIGINFO | BSD signal。由Status Key产生,通常是CTRL+T。发送给所有Foreground Group的进程 |
SIGINT | 由Interrupt Key产生,通常是CTRL+C或者DELETE。发送给所有ForeGround Group的进程 |
SIGIO | 异步IO事件 |
SIGIOT | 实现相关的硬件异常,一般对应SIGABRT |
SIGKILL | 无法处理和忽略。中止某个进程 |
SIGLWP | 由Solaris Thread Libray内部使用 |
SIGPIPE | 在reader中止之后写Pipe的时候发送 |
SIGPOLL | 当某个事件发送给Pollable Device的时候发送 |
SIGPROF | Setitimer指定的Profiling Interval Timer所产生 |
SIGPWR | 和系统相关。和UPS相关。 |
SIGQUIT | 输入Quit Key的时候(CTRL+\)发送给所有Foreground Group的进程 |
SIGSEGV | 非法内存访问 |
SIGSTKFLT | Linux专用,数学协处理器的栈异常 |
SIGSTOP | 中止进程。无法处理和忽略。 |
SIGSYS | 非法系统调用 |
SIGTERM | 请求中止进程,kill命令缺省发送 |
SIGTHAW | Solaris专用,从Suspend恢复时候发送 |
SIGTRAP | 实现相关的硬件异常。一般是调试异常 |
SIGTSTP | Suspend Key,一般是Ctrl+Z。发送给所有Foreground Group的进程 |
SIGTTIN | 当Background Group的进程尝试读取Terminal的时候发送 |
SIGTTOU | 当Background Group的进程尝试写Terminal的时候发送 |
SIGURG | 当out-of-band data接收的时候可能发送 |
SIGUSR1 | 用户自定义signal 1 |
SIGUSR2 | 用户自定义signal 2 |
SIGVTALRM | setitimer函数设置的Virtual Interval Timer超时的时候 |
SIGWAITING | Solaris Thread Library内部实现专用 |
SIGWINCH | 当Terminal的窗口大小改变的时候,发送给Foreground Group的所有进程 |
SIGXCPU | 当CPU时间限制超时的时候 |
SIGXFSZ | 进程超过文件大小限制 |
SIGXRES | Solaris专用,进程超过资源限制的时候发送 |
更多推荐
已为社区贡献1条内容
所有评论(0)