当前位置: 首页 > news >正文

10 信号

信号是由用户、系统、或者进程发送给目标进程的信息,以通知目标进程某个状态的改变或系统异常

linux信号可由如下条件产生:

  • 前台进程,用户可以通过输入特殊的终端符发送信号(ctrl + c 中断)
  • 系统异常
  • 系统状态变化
  • 运行kill命令或调用kill函数

10.1 linux信号概述

一个进程给其他进程发送信号的API是kill函数,把信号sig发送给pid参数指定的进程

1 #include <sys/types.h>
2 #include <signal.h>
3 int kill( pid_t pid, int sig);

pid>0  //信号发送给PID为pid的进程
pid=0  //信号发送给本进程组内的其他进程
pid=-1  //发送给除init之外的所有进程,但发送者要拥有对目标进程发送信号的权限
pid<-1  //信号发送给组ID为-pid的进程组中的所有成员

 

接收函数:

1 #include <signal.h>
2 typedef void (*__sighandler_t)(int);

 在bits/signum.h头文件中还定义了信号的两种其他处理方式--SIG_IGN(忽略目标信号)和SIG_DFL(默认处理方式):

1 #include <bits/signum.h>
2 #define SIG_DFL ((__sighandler_t) 0)
3 #define SIG_IGN ((__sighandler_t) 1)

 几个需要记住的信号:

SIGHUP  控制终端挂起

SIGPIPE  往读终端被关闭的管道或者socket连接中写数据

SIGURG  socket连接上接收到紧急数据

 

10.2 信号函数

两个信号处理函数

_sighandler_t signal(int sig, _sighandler_t _handler);
int sigaction(int sig, const struct sigaction* act, struct sigaction* oact);

 后者提供更健壮的接口

 

10.3 信号集

1 #include <bits/sigset.h>
2 #define _SIGSET_NWORDS (1024/(8*sizeof(unsigned long int)))
3 typedef struct{
4 unsigned long int __val[_SIGSET_NWORDS];
5 }__sigset_t;

 

由定义可见,sigset_t实际上是一个长整型数组,数组的每个元素的每个位表示一个信号。这种定义方式和文件描述符集fd_set类似。Linux提供了如下一组函数来设置、修改、删除和查询信号集:

1 #include <signal.h>
2 int sigempty(sigset_t* set);    //清空信号集
3 int sigfillset(sigset_t* set);    //在信号集中设置所有信号
4 int sigaddset(sigset_t* _set, int _signo);    //将信号添加到信号集
5 int sigdelset(sigset_t* _set, int _signo);    //将信号从信号集中删除
6 int sigismember(_const sigset_t* _set, int _signo);    //测试是否在信号集中

可以利用sigaction结构体的sa_mask成员来设置进程的信号掩码。此外,如下函数也可以用于设置或查看进程的信号掩码:

1 int sigprocmask(int _how, _const sigset_t* _set, sigset_t* _oset);

_how可以设置为:
SIG_BLOCK;
SIG_UNBLOCK;
SIG_SETMASK;

设置进程信号掩码后,被屏蔽的信号将不可能被进程接收。如果给进程发送一个被屏蔽的信号,则操作系统将该信号设置为进程的一个被挂起的信号。如果我们取消对被挂起信号的屏蔽,则它能立即被进程接收到。获得进程当前被挂起的信号集:

int sigpending(sigset_t* set);

 

10.4 统一事件源

把信号的主要处理逻辑放在程序的主循环中,当信号处理函数被触发时,它只是简单的通知主循环接收到信号,并把信号值传递给主循环,主循环在根据接收到的信号值执行目标信号对应的逻辑代码。信号处理函数通常使用管道将信号“传递”给主循环:信号处理函数往管道写入信号值,主循环从管道读出信号值。主程序使用IO多路复用来监听管道的读端文件描述符上的可读事件。如此一来,信号事件就能够和其他IO时间一样被处理,即统一事件源。如Libevent IO框架库和xinetd超级服务。

 

10.5 网络编程相关信号

SIGHUP

当挂起进程的控制终端时,SIGHUP信号将被触发,通常利用SIGHUP信号来强制服务器重读配置文件

SIGPIPE

往一个读终端关闭的管道或socket连接中写数据将引发SIGPIPE信号

SIGURG

内核通知应用程序带外数据到达的主要方式有两种,一是用select接受到带外数据返回异常,二是用SIGURG信号

 

转载于:https://www.cnblogs.com/raichen/p/5036997.html

相关文章:

  • Visual Assist X 10.8.2052的Crack破解补丁. 2014.11.05 (General release.)
  • 修改字符串 ToCharArray()
  • Java读取mat文件
  • 费用流
  • 字符串格式化 (%操作符)
  • Memcached简介
  • dialog工具,让脚本迈向图形化
  • 如何学好编程(三)---四步成为编程精英
  • ios项目中引用其他项目复习
  • 检测一下你的专业指数:2015年十大测试工具你认识几个?
  • 1126 求递推序列的第N项(51nod)
  • Char、AnsiChar、WideChar、PChar、PAnsiChar、PWideChar 的用法
  • spring-data-jpa 多数据源
  • 利用partial关键字声明分部类和分部方法
  • linux下搭建LAMP
  • 【跃迁之路】【699天】程序员高效学习方法论探索系列(实验阶段456-2019.1.19)...
  • angular2 简述
  • css系列之关于字体的事
  • Docker 笔记(2):Dockerfile
  • JAVA 学习IO流
  • JS数组方法汇总
  • OpenStack安装流程(juno版)- 添加网络服务(neutron)- controller节点
  • tab.js分享及浏览器兼容性问题汇总
  • webpack项目中使用grunt监听文件变动自动打包编译
  • 高性能JavaScript阅读简记(三)
  • 开发了一款写作软件(OSX,Windows),附带Electron开发指南
  • 聊聊redis的数据结构的应用
  • 排序(1):冒泡排序
  • 前端每日实战:61# 视频演示如何用纯 CSS 创作一只咖啡壶
  • 如何解决微信端直接跳WAP端
  • 算法-插入排序
  • 学习Vue.js的五个小例子
  • 找一份好的前端工作,起点很重要
  • 扩展资源服务器解决oauth2 性能瓶颈
  • ​LeetCode解法汇总307. 区域和检索 - 数组可修改
  • ​Linux Ubuntu环境下使用docker构建spark运行环境(超级详细)
  • #【QT 5 调试软件后,发布相关:软件生成exe文件 + 文件打包】
  • #微信小程序:微信小程序常见的配置传旨
  • (1)Map集合 (2)异常机制 (3)File类 (4)I/O流
  • (14)目标检测_SSD训练代码基于pytorch搭建代码
  • (C语言)求出1,2,5三个数不同个数组合为100的组合个数
  • (Matalb时序预测)WOA-BP鲸鱼算法优化BP神经网络的多维时序回归预测
  • (分布式缓存)Redis持久化
  • (附源码)springboot 基于HTML5的个人网页的网站设计与实现 毕业设计 031623
  • (附源码)springboot优课在线教学系统 毕业设计 081251
  • (附源码)ssm户外用品商城 毕业设计 112346
  • (四)docker:为mysql和java jar运行环境创建同一网络,容器互联
  • (原创)Stanford Machine Learning (by Andrew NG) --- (week 9) Anomaly DetectionRecommender Systems...
  • (转)如何上传第三方jar包至Maven私服让maven项目可以使用第三方jar包
  • .bat批处理(四):路径相关%cd%和%~dp0的区别
  • .MSSQLSERVER 导入导出 命令集--堪称经典,值得借鉴!
  • .NET CF命令行调试器MDbg入门(一)
  • .NET delegate 委托 、 Event 事件
  • .Net mvc总结
  • .Net 应用中使用dot trace进行性能诊断