目录
1、信号的概念
1、信号是在软件层次上对中断机制的一种模拟,是一种异步通信方式
2、信号可以直接进行用户空间进程和内核进程之间的交互,内核进程也可以利用它来 通知 用户空间进程发生了哪些系统事件
3、如果该进程当前并未处于执行态,则该信号就由内核保存起来,直到该进程恢复执行再传递给它
4、如果一个信号被进程设置为阻塞,则该信号的传递被延迟,直到其阻塞被取消时才被传递给进程
2、进程对信号的处理方式
1、忽略信号
对信号不做处理,但是有两个信号是不能忽略: 9)SIGKILL 19)SIGSTOP
2、捕获信号
自定义信号处理函数,当信号发生的时候,立即执行自定义信号处理函数。
3、执行缺省操作(执行默认操作)
每个信号都有自己默认的处理函数。
3、信号有哪些:kill -l
1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP
6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1
11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM
16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP
21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ
26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR
31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3
38) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8
43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7
58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2
63) SIGRTMAX-1 64) SIGRTMAX
4、信号相关API
4.1 signal
sighandler_t signal(int signum, sighandler_t handler);
/*
功能:捕获信号,为信号注册处理函数;
头文件:
#include <signal.h>
参数:
@signum:指定要捕获的信号;可以填信号编号,也可以填对应的宏;
@handler:
1.SIG_IGN:忽略信号;
2.SIG_DFL:执行默认操作;
3.函数指针变量,该函数指针能够指向返回值是void类型,且参数列表是int类型的函数。
返回值:
成功,返回该信号的上一个信号处理函数首地址;
失败,返回SIG_ERR,更新errno;
*/
4.2 kill
int kill(pid_t pid, int sig);
/*
功能:发送信号给指定的进程;
头文件:
#include <sys/types.h>
#include <signal.h>
参数:
@pid:指定要发送给哪个进程或者哪个进程组;
pid > 0, 将信号发送给指定进程;
pid == 0, 将信号发送给当前进程组下的所有进程;
pid == -1, 将信号发送给当前进程权限所能发送到的所有进程,除了1号进程.
pid < -1, 将进程发送给指定进程组下的所有进程,进程组id == -pid;
@sig:指定要发送的信号; 62个信号之一
返回值:
成功,返回0;
失败,返回-1,更新errno;
*/
4.3 raise
int raise(int sig);
/*
功能:给自己发送一个信号
int raise(int sig) 等同于 kill(getpid(), sig)
*/
4.4 alarm
unsigned int alarm(unsigned int seconds);
/*
功能:设置一个定时器,等时间结束后,产生一个14) SIGALRM 时钟信号;
头文件:
#include <unistd.h>
参数:
@seconds:设置定时器的时间,以秒为单位;
seconds == 0,删除定时器,并且不会产生14号信号;
返回值:
>0, 返回上一个时钟没有走完的时间;
=0, 没有设置定时器,或者上一次设置的定时器已经走完了;
*/
4.5 pause
int pause(void);
/*
功能:使当前进程阻塞,直到进程收到任意信号,并从信号处理函数中返回;
头文件:
#include <unistd.h>
返回值:
-1,errno == EINTR,pause会一直阻塞,直到进程收到任意信号,并从信号处理函数中返回,解除阻塞;
*/
5、应用程序:用信号回收僵尸进程
在前面Linux 进程基础5.2.3中,提到了可以用子进程在退出的时候,给父进程发送一个SIGCHLD信号,来回收僵尸进程。
void handler(int sig)
{
while(waitpid(-1,NULL, WNOHANG) > 0);
return;
}
int main(int argc, const char *argv[])
{
sighandler_t s = signal(SIGCHLD, handler);
int i = 0;
pid_t pid = 0;
while(i < 100)
{
pid = fork();
if( 0 == pid) {
exit(0); //直接退出子进程
}
i++;
}
while(1)
sleep(1); //父进程最后运行到这里
return 0;
}
6、应用程序:接收到信号后输出一句话代表接收到信号
int main(int argc, char *argv[])
{
int time_left;
signal(SIGINT, sig_handler);
signal(SIGQUIT, sig_handler);
time_left = sleep(10);
printf("end sleep ... time_left=%d\n", time_left);
while(1);
return 0;
}
void sig_handler(int signo)
{
if (signo == SIGINT)
printf("I received a SIGINT!\n");
if (signo == SIGQUIT)
printf("I received a SIGQUIT!\n");
}