Linux信号通信

来源:互联网 发布:phpmyadmin同步数据库 编辑:程序博客网 时间:2024/05/21 04:02

信号通信很简单,将特定信号传递给进程,使进程进行相应动作,以此达到通信的目的。

linux信号量很多在文章最后列举;

信号通信函数结构

#include <signal.h>void (*signal(int signo,void(*func)(int)))(int)
可以看到信号函数结构比较复杂

signal函数本身是个函数指针,参数为int型。

signal函数参数:

signo:具体信号名称或者编号

第二个参数func:

    1、SIG_IGN  忽略此信号

    2、SIG_DFL 按默认的方式处理此信号

    3、信号处理函数名:使用该函数处理

信号通信小例程:

#include <signal.h>#include <stdio.h>#include <stdlib.h>void my_func(int sign_no){if(sign_no==SIGINT)printf("I have get SIGINT\n");else if(sign_no==SIGQUIT)printf("I have get SIGQUIT\n");}int main(){printf("Waiting for signal SIGINT or SIGQUIT \n ");/*注册信号处理函数*/signal(SIGINT, my_func);signal(SIGQUIT, my_func);pause();exit(0);}
在主函数中注册信号处理方式,这里没有采用两个宏处理,采用的是指定函数处理,注册完信号处理函数后,进程将会执行pause等待信号来临,特定信号出现,将会跳进信号处理函数func,结束进程。

试验方式是先将此进程跑起来,利用 ps aux指令获取进程ID,采用kill命令向进程传递信号,观察进程运行状况,达到进程通信的目的。

[root@localhost signal]# gcc -o mysignal mysignal.c [root@localhost signal]# lsmysignal  mysignal.c[root@localhost signal]# ./mysignal Waiting for signal SIGINT or SIGQUIT 
切换终端执行ps aux

root     27544  0.0  0.4  11592  3308 ?        Ss   21:03   0:04 sshd: root@pts/0 root     27548  0.0  0.2   6828  1696 pts/0    Ss+  21:03   0:00 -bashroot     28112  0.0  0.1   3840  1016 ?        S    22:51   0:00 /usr/libexec/hald-addon-rfkill-killswitchroot     28202  0.1  0.4  11592  3308 ?        Rs   23:02   0:00 sshd: root@pts/1 root     28206  0.0  0.2   6720  1584 pts/1    Ss   23:02   0:00 -bashpostfix  28232  0.0  0.3  13440  2468 ?        S    23:04   0:00 pickup -l -t fifo -uroot     28241  0.0  0.0   1848   352 tty2     S+   23:06   0:00 ./mysignalroot     28243  0.0  0.1   6532  1040 pts/1    R+   23:06   0:00 ps aux
查看到进程编号28241,向进程发送信号。

[root@localhost ~]# kill -s SIGQUIT  28241

另一终端查看进程运行情况:

[root@localhost signal]# ./mysignal Waiting for signal SIGINT or SIGQUIT  I have get SIGQUIT  [root@localhost signal]# 
可以看到进程接收到信号并执行相应动作。证明通信正常,这就是简单的信号通信。

可以将信号注册函数中第二个参数改为SIG_IGN(忽略收到的信号),即便使进程接收到信号,进程也不会动作。

将信号注册函数第二个参数改为SIG_DFL(按信号默认的方式处理),进程将会按信号特定的含义执行相应动作。这里不在演示。

SIGHUP:本信号在用户终端结束时发出,通常是在终端的控制进程结束时,通知同一会话期内的各个作业,这时他们与控制终端不在关联。比如,登录linux时,系统会自动分配给登录用户一个控制终端,在这个终端运行的所有程序,包括前台和后台进程组,一般都属于同一个会话。当用户退出时,所有进程组都将收到该信号,这个信号的默认操作是终止进程。此外对于与终端脱离关系的守护进程,这个信号用于通知它重新读取配置文件。
SIGINT:程序终止信号。当用户按下CRTL+C时通知前台进程组终止进程。
SIGQUIT:Ctrl+\控制,进程收到该信号退出时会产生core文件,类似于程序错误信号。
SIGILL:执行了非法指令。通常是因为可执行文件本身出现错误,或者数据段、堆栈溢出时也有可能产生这个信号。
SIGTRAP:由断点指令或其他陷进指令产生,由调试器使用。
SIGABRT:调用abort函数产生,将会使程序非正常结束。
SIGBUS:非法地址。包括内存地址对齐出错。比如访问一个4个字长的整数,但其地址不是4的倍数。它与SIGSEGV的区别在于后者是由于对合法地址的非法访问触发。
SIGFPE:发生致命的算术运算错误。
SIGKILL:用来立即结束程序的运行。
SIGUSR1:留给用户使用,用户可自定义。
SIGSEGV:访问未分配给用户的内存区。或操作没有权限的区域。
SIGUSR2:留给用户使用,用户可自定义。
SIGPIPE:管道破裂信号。当对一个读进程已经运行结束的管道执行写操作时产生。
SIGALRM:时钟定时信号。由alarm函数设定的时间终止时产生。
SIGTERM:程序结束信号。shell使用kill产生该信号,当结束不了该进程,尝试使用SIGKILL信号。
SIGSTKFLT:堆栈错误。
SIGCHLD:子进程结束,父进程会收到。如果子进程结束时父进程不等待或不处理该信号,子进程会变成僵尸进程。
SIGCONT:让一个停止的进程继续执行。
SIGSTOP:停止进程执行。暂停执行。
SIGTSTP:停止运行,可以被忽略。Ctrl+z。
SIGTTIN:当后台进程需要从终端接收数据时,所有进程会收到该信号,暂停执行。
SIGTTOU:与SIGTTIN类似,但在写终端时产生。
SIGURG:套接字上出现紧急情况时产生。
SIGXCPU:超过CPU时间资源限制时产生的信号。
SIGXFSZ:当进程企图扩大文件以至于超过文件大小资源限制时产生。
SIGVTALRM:虚拟使用信号。计算的是进程占用CPU调用的时间。
SIGPROF:包括进程使用CPU的时间以及系统调用的时间。
SIGWINCH:窗口大小改变时。
SIGIO:文件描述符准备就绪,表示可以进行输入输出操作。
SIGPWR:电源失效信号。
SIGSYS:非法的系统调用。