阅读《Linux高性能服务器编程》的笔记
一 Linux信号概述
-
发送信号
#include <sys/types.h> #include <signal.h> int kill(pid_t pid, int sig) /* pid: <-1,发送给组ID为-pid的进程组中的所有成员 -1,发送给除init进程外的所有进程,发送者需要拥有对目标进程发送信号的权限 0,本进程组内的其他进程 >0,发送给PID为pid的进程 sig: 0,不发生任何信号 返回值: 0,成功 -1,失败,设置errno EINVAL:无效信号 EPERM:该进程没有权限发送给任何一个目标进程 ESRCH:目标进程或进程组不存在 */
-
中断系统调用
- 如果程序在执行阻塞状态的系统调用时,接收到信号,并且设置了信号函数,默认情况下系统调用被中断,并设置errno被设置为EINTR。
- 使用sigaction函数为信号设置SA_REETART标志以自动重启被该信号中断的系统调用。
- 对于默认行为是暂停进程的信号(SIGSTOP、SIGTTIN),如果没有设置信号处理函数,也可以中断一些系统调用(connect、epoll_wait)
二 信号函数
-
signal系统调用
#include <signal.h> typedef void(*_signalhandler_t)(int); _sighandler_t signal(int sig, _sighandler_t _handler); /* sig:要捕获的信号类型 _handler:信号sig的处理函数 返回值: 成功,一个函数指针。前一次调用signal函数时传入的函数指针 失败:SIG_ERR,设置errno */
-
sigaction系统调用
#include <signal.h> int signalaction(int sig, const struct sigaction* act, struct sigaction* oact); /* sig:要捕获的信号类型 act:新的信号处理方式 oact:先前的信号处理方式(不为NULL的时候) 返回值:0(成功),-1(失败,设置errno) */ //sigaction结构体比较重要的成员 struct sigaction { _sighandler_t sa_handler;//信号处理函数 _sigset_t sa_mask;//信号掩码,信号处理函数中的信号集 int sa_flags;//设置程序收到信号时的行为 };
三 信号集
-
信号集函数
#include <bits/sigset.h> #include <signal.h> int sigemptyset(sigset_t* set) //清空信号集 int sigfillset(sigset_t* set) //在信号集中设置所有信号 int sigaddset(sigset_t* set, int _signo) //将_signo添加至信号集中 int sigdelset(sigset_t* _set, int _signo) //将信号_signo从信号集中剔除 int sigismember(_const sigset_t* _set, int _signo) //测试_signo是否在信号集中
-
使用管道通知主进程信号到来
四 网络编程相关信号
-
SIGHUP
- 当挂起进程的控制终端时,SIGHUP信号将被触发
- 对于没有控制终端的网络后台程序,通常利用SIGHUP信号来强制服务器重读配置文件。
-
SIGPIPE
-
默认情况,往一个读端关闭的管道或socket连接中写数据将引发SIGPIPE信号。
-
引起SIGPIPE信号的写操作将设置errno为EPIPE。
-
也可以用I/O复用函数来检测管道和socket连接的读端是否已经关闭。poll为例,
- 当管道读端关闭,写端文件描述符上的POLLHUP事件被触发。
- 当socket连接被对方关闭时,socket上的POLLRDHUP事件被触发。
-
-
SIGURG
- 内核通知应用程序带外数据到达有两种方法
- I/O复用。select等函数在接收到带外数据时将返回,并向应用程序报告socket上的异常事件。
- SIGURG。
- 内核通知应用程序带外数据到达有两种方法