10 信号
2015-12-11 09:48
344 查看
信号是由用户、系统、或者进程发送给目标进程的信息,以通知目标进程某个状态的改变或系统异常
linux信号可由如下条件产生:
前台进程,用户可以通过输入特殊的终端符发送信号(ctrl + c 中断)
系统异常
系统状态变化
运行kill命令或调用kill函数
[b]10.1 linux信号概述[/b]
一个进程给其他进程发送信号的API是kill函数,把信号sig发送给pid参数指定的进程
pid>0 //信号发送给PID为pid的进程
pid=0 //信号发送给本进程组内的其他进程
pid=-1 //发送给除init之外的所有进程,但发送者要拥有对目标进程发送信号的权限
pid<-1 //信号发送给组ID为-pid的进程组中的所有成员
接收函数:
在bits/signum.h头文件中还定义了信号的两种其他处理方式--SIG_IGN(忽略目标信号)和SIG_DFL(默认处理方式):
几个需要记住的信号:
SIGHUP 控制终端挂起
SIGPIPE 往读终端被关闭的管道或者socket连接中写数据
SIGURG socket连接上接收到紧急数据
[b]10.2 信号函数[/b]
两个信号处理函数
后者提供更健壮的接口
[b]10.3 信号集[/b]
由定义可见,sigset_t实际上是一个长整型数组,数组的每个元素的每个位表示一个信号。这种定义方式和文件描述符集fd_set类似。Linux提供了如下一组函数来设置、修改、删除和查询信号集:
可以利用sigaction结构体的sa_mask成员来设置进程的信号掩码。此外,如下函数也可以用于设置或查看进程的信号掩码:
_how可以设置为:
SIG_BLOCK;
SIG_UNBLOCK;
SIG_SETMASK;
设置进程信号掩码后,被屏蔽的信号将不可能被进程接收。如果给进程发送一个被屏蔽的信号,则操作系统将该信号设置为进程的一个被挂起的信号。如果我们取消对被挂起信号的屏蔽,则它能立即被进程接收到。获得进程当前被挂起的信号集:
[b]10.4 统一事件源[/b]
把信号的主要处理逻辑放在程序的主循环中,当信号处理函数被触发时,它只是简单的通知主循环接收到信号,并把信号值传递给主循环,主循环在根据接收到的信号值执行目标信号对应的逻辑代码。信号处理函数通常使用管道将信号“传递”给主循环:信号处理函数往管道写入信号值,主循环从管道读出信号值。主程序使用IO多路复用来监听管道的读端文件描述符上的可读事件。如此一来,信号事件就能够和其他IO时间一样被处理,即统一事件源。如Libevent IO框架库和xinetd超级服务。
[b]10.5 网络编程相关信号[/b]
SIGHUP
当挂起进程的控制终端时,SIGHUP信号将被触发,通常利用SIGHUP信号来强制服务器重读配置文件
SIGPIPE
往一个读终端关闭的管道或socket连接中写数据将引发SIGPIPE信号
SIGURG
内核通知应用程序带外数据到达的主要方式有两种,一是用select接受到带外数据返回异常,二是用SIGURG信号
linux信号可由如下条件产生:
前台进程,用户可以通过输入特殊的终端符发送信号(ctrl + c 中断)
系统异常
系统状态变化
运行kill命令或调用kill函数
[b]10.1 linux信号概述[/b]
一个进程给其他进程发送信号的API是kill函数,把信号sig发送给pid参数指定的进程
#include <sys/types.h> #include <signal.h> int kill( pid_t pid, int sig);
pid>0 //信号发送给PID为pid的进程
pid=0 //信号发送给本进程组内的其他进程
pid=-1 //发送给除init之外的所有进程,但发送者要拥有对目标进程发送信号的权限
pid<-1 //信号发送给组ID为-pid的进程组中的所有成员
接收函数:
#include <signal.h> typedef void (*__sighandler_t)(int);
在bits/signum.h头文件中还定义了信号的两种其他处理方式--SIG_IGN(忽略目标信号)和SIG_DFL(默认处理方式):
#include <bits/signum.h> #define SIG_DFL ((__sighandler_t) 0) #define SIG_IGN ((__sighandler_t) 1)
几个需要记住的信号:
SIGHUP 控制终端挂起
SIGPIPE 往读终端被关闭的管道或者socket连接中写数据
SIGURG socket连接上接收到紧急数据
[b]10.2 信号函数[/b]
两个信号处理函数
_sighandler_t signal(int sig, _sighandler_t _handler); int sigaction(int sig, const struct sigaction* act, struct sigaction* oact);
后者提供更健壮的接口
[b]10.3 信号集[/b]
#include <bits/sigset.h> #define _SIGSET_NWORDS (1024/(8*sizeof(unsigned long int))) typedef struct{ unsigned long int __val[_SIGSET_NWORDS]; }__sigset_t;
由定义可见,sigset_t实际上是一个长整型数组,数组的每个元素的每个位表示一个信号。这种定义方式和文件描述符集fd_set类似。Linux提供了如下一组函数来设置、修改、删除和查询信号集:
#include <signal.h> int sigempty(sigset_t* set); //清空信号集 int sigfillset(sigset_t* set); //在信号集中设置所有信号 int sigaddset(sigset_t* _set, int _signo); //将信号添加到信号集 int sigdelset(sigset_t* _set, int _signo); //将信号从信号集中删除 int sigismember(_const sigset_t* _set, int _signo); //测试是否在信号集中
可以利用sigaction结构体的sa_mask成员来设置进程的信号掩码。此外,如下函数也可以用于设置或查看进程的信号掩码:
int sigprocmask(int _how, _const sigset_t* _set, sigset_t* _oset);
_how可以设置为:
SIG_BLOCK;
SIG_UNBLOCK;
SIG_SETMASK;
设置进程信号掩码后,被屏蔽的信号将不可能被进程接收。如果给进程发送一个被屏蔽的信号,则操作系统将该信号设置为进程的一个被挂起的信号。如果我们取消对被挂起信号的屏蔽,则它能立即被进程接收到。获得进程当前被挂起的信号集:
int sigpending(sigset_t* set);
[b]10.4 统一事件源[/b]
把信号的主要处理逻辑放在程序的主循环中,当信号处理函数被触发时,它只是简单的通知主循环接收到信号,并把信号值传递给主循环,主循环在根据接收到的信号值执行目标信号对应的逻辑代码。信号处理函数通常使用管道将信号“传递”给主循环:信号处理函数往管道写入信号值,主循环从管道读出信号值。主程序使用IO多路复用来监听管道的读端文件描述符上的可读事件。如此一来,信号事件就能够和其他IO时间一样被处理,即统一事件源。如Libevent IO框架库和xinetd超级服务。
[b]10.5 网络编程相关信号[/b]
SIGHUP
当挂起进程的控制终端时,SIGHUP信号将被触发,通常利用SIGHUP信号来强制服务器重读配置文件
SIGPIPE
往一个读终端关闭的管道或socket连接中写数据将引发SIGPIPE信号
SIGURG
内核通知应用程序带外数据到达的主要方式有两种,一是用select接受到带外数据返回异常,二是用SIGURG信号
相关文章推荐
- 为tomcat做到开机并后台运行
- spring mvc 简介和实例
- exec-maven-plugin
- Unity 动画曲线-AnimationCurve 实例
- 属性 set ,get 方法
- tomcat的安装及使用
- 单例类的使用方法
- 使用JDBCTMEPLATE插入数据时,事务不回滚
- make执行过程
- 接口和抽象类
- js------for-in
- Object-C NSLog 常用输出基本数据类型格式
- java.lang.UnsupportedClassVersionError: *** : Unsupported major.minor version 51.0
- 五大常用算法之二:动态规划算法
- 个人遇到的浏览器兼容性
- mven-dependency-plugin 获取artifact
- java学习笔记_高级篇必会(可变参数,枚举)
- Android 的通用权限
- JSP 获得Spring 注射对象
- 自建表和从系统外导入数据需要注意的问题