Linux信号
异步和同步的区别:
同步可以理解成串行执行,每个任务执行有先后顺序;
异步则是并行执行,你做你的事,我干我的事情,相互独立
信号是异步的,一个进程不必通过任何操作来等待信号的到达。事实上,进程也不知道信号到底什么时候到达。一般来说,我们只需要在进程中设置信号相应的处理函数,当有信号到达的时候,由系统异步触发相应的处理函数即可。
产生信号
① 硬件产生信号:通过终端按键产生信号
ctrl -c是 SIGINT 信号
ctrl -z 是SIGSTOP信号
ctrl -\ 是SIGQUIT信号
② 输入命令经过系统调用产生信号:kill命令产生信号,调用的是kill()函数 ;
kill函数可以给一个指定的进程发送指定的信号。
raise函数可以给当前进程发送指定的信号(自己给自己发信号)
③ 由软件条件产生信号:调用alarm函数可以设定一个闹钟,也就是告诉内核在seconds秒之后给当前进程发SIGALRM信号,该信号的默认处理动作是终止当前进程。
#include <unistd.h>
#include <stdio.h>
int main(void)
{
int counter;
alarm(1);
for(counter=0; 1; counter++)
printf("counter=%d ", counter);
return 0;
}
处理信号
signal()函数对信号进行处理
#include <signal.h>
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);
例子1:通过SIG_IGN来忽略SIGINT信号
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
int main()
{
int i = 0;
signal(SIGINT, SIG_IGN); //通过SIG_IGN来忽略SIGINT信号
do
{
write(1,"*", 1);
sleep(1);
i++;
}while(i < 10);
exit(0);
}
例子2:通过自定义的func函数处理信号
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
static void func(int signo)
{
write(1,"\n ...coming a signal named SIGINT ,func is called\r\n", 50);
}
int main()
{
int i = 0;
signal(SIGINT,func);
do
{
write(1,"*", 1);
sleep(1);
i++;
}while(i<10);
exit(0);
}
[xuanmiao@192 ~]$ 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
来一段烧脑的代码
#include <stdio.h>
enum { RED, GREEN, BLUE };
void OutputSignal(int sig)
{
printf("The signal you /'ve input is: ");
switch(sig)
{
case RED:
puts("RED!");
break;
case GREEN:
puts("GREEN!");
break;
case BLUE:
puts("BLUE!");
break;
}
return;
}
void ( *signal( int sig, void (*func)(int) ) ) (int)
{
puts("Hello, world!");
func(sig);
return func;
}
int main(void)
{
( *signal (GREEN, &OutputSignal) ) (RED);
return 0;
}
程序的执行结果:
[xuanmiao@192 Demo]$ ./test
Hello, world!
The signal you /'ve input is: GREEN!
The signal you /'ve input is: RED!
这里signal函数的声明 void ( *signal( int sig, void (*func)(int)))(int) 可以替换成
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);
对应的函数调用替换成
sighandler_t signal( int sig, sighandler_t func)
{
puts("Hello, world!");
func(sig);
return func;
}
参考文章: