1.信号基本概念
Linux系统上运行有多个进程,其中许多都是独立运行。然而,有些进程必须相互合作以达成预期目的,因此彼此间需要通信和同步机制。
读写磁盘文件中的信息是进程间通信的方法之一。可是,对许多程序来说,这种方法既慢又缺乏灵活性。因此,像所有现代UNIX实现那样,Linux 也提供了丰富的进程间通信(IPC)机制,如下所示。
在 Linux 系统上输入 kill -l 来列出系统使用的信号,下面是我提供的一些信号
$ 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 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
信号:内核与应用进程之间,以及应用进程与应用进程之间传递控制命令的方法
2.举例
例子1
sig_kill.c
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
int main(void)
{
pid_t pid;
pid = fork(); // 创建进程
if(pid > 0) // 父进程
{
sleep(10);
kill(pid, SIGKILL); // 父进程向子进程发送kill信号,结束子进程
}
else if(pid == 0) // 子进程
{
int i = 0;
printf("child process id = %d\n", getpid()); // 子进程id号
while(1)
{
printf("count to %d\n", ++i);
sleep(1);
}
}
else
perror("fork");
return 0;
}
signal函数----重新定义信号
例子2
signal.c
#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<unistd.h>
#include<signal.h>
#include<wait.h>
void function(int signo);
int main(void)
{
int i = 0;
printf("pid = %d\n", getpid()); // 该进程ID号
signal(SIGINT, function);
signal(SIGKILL, function);
while(1)
{
printf("count to %d\n", ++i);
sleep(1);
}
return 0;
}
void function(int signo)
{
if(signo == SIGINT) // 可以重新定义的信号
{
printf("you have just triggered a ctrl+c operation.\n");
exit(1);
}
else if(signo == SIGKILL) // 不可修改的信号
printf("trig a SIGKILL signal.\n");
}
kill.c
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <signal.h>
int main(int argc, char *argv[])
{
kill(atoi(argv[1]), SIGKILL); // 转化为整数
return 0;
}
编译 gcc kill.c -o kill
运行 ./kill 3160 (3160为signal.c的进程号) 无法实现,因为SIGKILL无法重新定义
例子3
#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<unistd.h>
#include<signal.h>
#include<wait.h>
//自定义的信号处理函数
void My_Fun(int sig)
{
if(SIGRTMIN == sig)
{
printf("MIN!\n");
}
if(SIGRTMAX == sig)
{
printf("MAX!\n");
}
}
int main()
{
//注册信号处理函数
signal(SIGRTMIN,My_Fun);
signal(SIGRTMAX,My_Fun);
//挂起10s
sleep(3);
//发出信号
kill(getpid(),SIGRTMIN); //getpid()函数用于获取当前进程的pid.
kill(getpid(),SIGRTMAX);
return 0;
}