Linux信号概述
Linux系统中,信号是一种通信的方式,其通常用作用户,系统或进程给目标进程发送的信息。
信号的作用:通知目标进程某个状态的改变或系统异常。
产生的条件:
- 对于终端程序:可以是用户输入的特殊的终端字符,比如ctrl+c是中断信号
- 系统异常,如浮点异常或非法内存访问
- 系统状态变化
- 用户运行kill命令或程序调用kill函数
程序必须处理(忽略可以算作处理的一种)一些常见信号
发送信号
进程给其他进程发送信号使用kill函数
#include<sys/types.h>
#include<signal.h>
int kill(pid_t pid,int sig);
- 作用:发送信号
- 参数
- pid:目标进程的id
- sig:发送的信号
- 返回值:
- 成功:0
- 失败:-1
信号处理方式
目标进程接收到信号后,需要一个接收函数来处理信号
#include<signal.h>
typedef void (*_sighandler_t)(int);
其中 sighandler_t为一个函数指针,可以用一个函数名给其赋值,int为这个函数的参数,void表示这个函数返回值为NULL。
这是用户自定义函数,信号还有忽略和默认这两种处理方式,其定义为
#include<bits/signum.h>
#define SIG_DFL((_sighandler_t)0)
#define SIG_ING((_sighandler_t)1)
SIG_DFL为默认处理方式,SIG_ING为忽略信号
中断系统调用
程序在执行处于阻塞状态的系统调用时接收到信号,且该信号被我们设置了处理函数,那么系统调用会被中断。
如果接收到的信号的是暂停进程的信号(如SIGSTOP),即使我们没为其设置处理函数,它也可以中断一些系统调用(如connect,epoll_wait)
信号函数
当我们接收到信号,就可以为信号设置一个处理函数,Linux中有两种信号处理函数,分别是signal和sigaction
#include<signal.h>
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);
- 作用:为信号设置处理函数
- 参数
- signum:信号的编号
- handler:函数指针,表示接收此信号要执行的函数的地址
- SIG_IGN:忽略这个信号
- SIG_DFL:按照默认动作执行这个信号
- 如果是一个函数,则受到信号时去执行这个函数
- 返回值
- 成功:函数指针,类型是sighandler_t
- 失败:SIG_ERR
#include<signal.h>
int sigaction(int sig, const struct sigaction *act, struct sigaciton *oact);
- 作用:为信号设置处理函数,或者获取信号的处理函数,或二者皆有可用来检查和更改信号处理操作,可以支持可靠、实时信号的处理,并且支持信号传递信息
- 参数:
-
- sig:信号的编号
- act:信号动作结构体,见下
struct sigaction
{
void (*sa_handler)(int signum); /*简单的信号处理函数指针*/
void (*sa_sigaction)(int signum, siginfo_t *info, void *context); /*复杂的信号处理函数指针*/
sigset_t sa_mask; /*信号阻塞集*/
int sa_flags; /*信号处理方式*/
};
网络编程相关信号
SIGHUP:
当挂起进程的控制终端时,SIGHUP信号将被触发。对于没有控制终端的网络后台程序,SIGHUB信号可以用来强制服务器重读配置程序。
SIGPIPE:
在默认情况下,往一个读端关闭的管道(或socket连接)中写数据将引发SIGPIPE信号。SIGPIPE信号的默认处理方式是结束进程。文章来源:https://www.toymoban.com/news/detail-819127.html
所以为了避免因为往读端关闭的管道写数据导致进程结束,我们可以用send函数的MSG_NOSIGNAL标志来禁用写操作触发SIGPIPE信号文章来源地址https://www.toymoban.com/news/detail-819127.html
到了这里,关于C++ Webserver从零开始:基础知识(五)——信号的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!