函数原型
NAME signal - ANSI C signal handling SYNOPSIS #include <signal.h> typedef void (*sighandler_t)(int); sighandler_t signal(int signum, sighandler_t handler);
signal函数具有注册功能,什么事都不干。只是告诉系统,当来信号signum时,按handler的方式处理。只有来信号时,才会调用这个函数。信号不来,永远不会调用这个函数。
用户能够通过输入CTRL+c、Ctrl+\,或者是终端驱动程序分配给信号控制字符的其他任何键来请求内核产生信号。
ctrl + c --> 2)SIGINT
ctrl + \ --> 3)SIGQUIT
以上两者都可以让程序退出。
代码
/************************************************************************* > File Name: hello.c > Author: KrisChou > Mail:zhoujx0219@126.com > Created Time: Mon 25 Aug 2014 09:25:15 AM CST ************************************************************************/ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/stat.h> #include <sys/types.h> #include <fcntl.h> #include <assert.h> #include <signal.h> #include <sys/select.h> void handler(int num) { printf("sig_num: %d \n", num); } int main(int argc, char* argv[]) { char buf[1024]; signal(2, handler); int iret ; fd_set read_set, ready_set ; FD_ZERO(&read_set); FD_SET(0, &read_set); while(1) { ready_set = read_set ; iret = select(1, &ready_set, NULL, NULL, NULL); if(iret == 0) { continue ; }else if(iret == -1) { perror("select"); continue ; }else { iret = read(0, buf, 1024); buf[iret] = '\0'; write(1, buf, strlen(buf)); } }
程序运行后先按ctrl+c,结果如下:
[purple@localhost review]$ gcc test.c [purple@localhost review]$ ./a.out ^Csig_num: 2 select: Interrupted system call hello world! hello world!
由于SIGINT已经通过signal(2, handler);进行注册了, 因此很显然当按下ctrl+c后,信号处理函数handler自然会捕捉到这个信号,因此会显示^Csig_num: 2 。
而select函数 会处理中断信号。收到中断信号,会返回-1。 因此显示select: Interrupted system call select 。
注意:select函数在3中情况下会返回,分别是:轮询时间到点会返回。收到信号会返回。描述符有活动会返回。
(顺带补充下:read 是 阻塞函数,收到信号时先处理信号, 接着继续等。)
之后程序运行就很显然了。有输入,select返回1,输入什么,就打印什么。按ctrl+d,select返回0,程序继续运行。