socketpair + signal + select 的套路
1:起因
最近在看代码时连续两次看到这三个函数的组合使用,为方便以后借鉴和回忆,先记录下来。
这三个函数的应用场景是这样的:
1.1 首先socketpair函数创建一对已连接套接字,返回的两个描述符(socketpair的第三个参数)都可以进行读写,但在单向通信的场景下一般将sv[0]作为读,sv[1]作为写。
1.2 signal函数用于监听进程接收的信号并作相应处理,这里讲监听SIGTERM(这个信号一般是系统将要杀死进程前发送给进程的信号,SIGTERM大概过三秒之后系统就会再发送SIGKILL信号到进程杀死进程,SIGKILL信号是监听不到的)信号,所以信号处理函数不要过长,且函数是可重入的。
1.3 select函数可以监听多个描述符的可读或可写状态实现I/O复用
1.4 用法就是先得到sv[0]和sv[1],设置signal监听SIGTERM,信号处理函数里向sv[1]写捕捉到的信号,select监听sv[0]的可读状态,一旦可读就执行程序被杀死前的打扫工作。信号处理函数做的就是将获得的信号写给sv[0]而已。
2:函数用法简介
2.1 socketpair
原型:int socketpair(int domain, int type, int protocol, int sv[2])
头文件:<sys/types.h> <sys/socket.h>
参数:
domain:一般是AF_UNIX,还有AF_LOCAL
type:SOCK_STREAM和SOCK_DGRAM
protocol:0
sv:sv[0],sv[1]分别保存创建好的已连接的套接字对,两个均可读写
2.2 signal
原型:sighandler_t signal(int signum, sighandler_t handler)
头文件:<signal.h>
参数:
signum:由SIGxxx组成的信号,具体可查 文章
handler:是一个参数为int返回值为void的函数指针
注:handler指向的信号处理函数一定要是可重入的,因为信号处理函数是异步触发的,如果处理函数不可重入则会导致意想不到的错误,同时信号处理函数要尽可能的短才好。什么是可重入可参考 文章
2.3 select
原型:int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout)
辅助函数: void FD_CLR(int fd, fd_set *set);
int FD_ISSET(int fd, fd_set *set);
void FD_SET(int fd, fd_set *set);
void FD_ZERO(fd_set *set);
头文件:<sys/select.h> <sys/time.h> <sys/types.h> <unistd.h>
参数:
nfds:所监听的描述符最大值加1
readfds:监听的可读描述符集合,由FD_SET函数加入
writefds:监听的可写描述符集合,由FD_SET函数加入
exceptfds:监听的发生错误的描述符集合,由FD_SET函数加入
timeout :select阻塞的超时时间
返回值:
>0:表示有几个描述达到了准备状态了,需要使用FD_ISSET来检验
=0:表示超时时间到了还是没有准备好的描述符
<0 : 出错
特点:
1:FD_SET将某个描述符记录在位图rfds中(rfds若是一个字节长度最多只能监听8个fd),select调用先清空rfds位图,在某个fd状态准备好后将它原先的位置1,之后FD_ISSET检测此fd对应的位图是否为1,为1即准备就绪。
2:参数timeout是struct timeval *类型,表示阻塞时间
NULL ---> 完全阻塞方式,一定要等到监听的fd有就绪的才返回(变成了可以监听多个fd的阻塞函数比如accept,recv等)
0 ---> 不阻塞,select函数执行后立即返回
>0 ---> 半阻塞,在timeout内阻塞,有状态改变即返回,timeout时间到也要返回
注:select每次都会清空此参数的值,所以必须每次执行select前都要设置一下此参数值否则很可能意外变为不阻塞的select.
3:好处
3.1 将信号处理过程与select关联起来易于管理。通常使用select还会监听其它要读写的文件描述符,这样把信号的处理也纳入进来一同管理程序分支显得少,更清晰。
3.2 大大减少了信号处理函数的复杂度。因为信号是异步的,处理函数就必须是可重入的,使用socketpair + signal,让处理函数只做一个系统调用write动作,且signal在信号处理函数期间还会阻塞,这样也相当于保护了信号处理函数。
socketpair + signal + select 的套路的更多相关文章
- sloop公共程序之总体描述
1:功能需求 开发一个公共库文件sloop.c,实现三个常用功能以供其它模块调用.三个功能如下: 功能一:实现一般的信号监听,调用模块只需传入要监听的信号和相应的回调函数就可以在信号到时调用回调函数处 ...
- python 模块初识
python的强大之处在于有丰富的实现各种功能的标准库和第三方库,另外还允许用户自己建立库文件, 标准模块(又称为库)包括sys, os, glob, socket, threading, _thre ...
- 第6章 初识MyBatis
6.1 什么是MyBatis Mybatis(前身是iBatis)是一个支持普通SQL查询.存储过程以及高级映射的持久层框架.MyBatis框架也被称为ORM(Object/Relational Ma ...
- 论consul正确的关闭姿势
最近在工作中发现一个有意思的现象,我用 ctrl+c 关闭本地 consul 的时候,报警系统并没有发出告警,说我的 node 异常,自己看了一下代码,发现 consul 的关闭还是有点猫腻的,仔细来 ...
- python系统模块
Python中大多数系统接口都集中在两个模块:sys和os.这么说有点过于简单化 还有一些其他的表转模块也属于这个领域他们包括: glob 用于文件名的扩展 socket 用于网络连接和进程间通信(I ...
- 最全的ORACLE-SQL笔记
-- 首先,以超级管理员的身份登录oracle sqlplus sys/bjsxt as sysdba --然后,解除对scott用户的锁 alter user scott account unloc ...
- Matplotlib数据可视化(6):饼图与箱线图
In [1]: from matplotlib import pyplot as plt import numpy as np import matplotlib as mpl mpl.rcParam ...
- Libevent学习之SocketPair实现
Libevent设计的精化之一在于把Timer事件.Signal事件和IO事件统一集成在一个Reactor中,以统一的方式去处理这三种不同的事件,更确切的说是把Timer事件和Signal事件融合到了 ...
- (转载) Linux IO模式及 select、poll、epoll详解
注:本文是对众多博客的学习和总结,可能存在理解错误.请带着怀疑的眼光,同时如果有错误希望能指出. 同步IO和异步IO,阻塞IO和非阻塞IO分别是什么,到底有什么区别?不同的人在不同的上下文下给出的答案 ...
随机推荐
- NUMA 体系架构
NUMA 体系架构 SMP 体系架构 NUMA 体系架构 NUMA 结构基本概念 Openstack flavor NUMA 策略 Nova 实现 NUMA 流程 1. SMP 体系架构 CPU 计算 ...
- USACO 1.5.4 Checker Challenge跳棋的挑战(回溯法求解N皇后问题+八皇后问题说明)
Description 检查一个如下的6 x 6的跳棋棋盘,有六个棋子被放置在棋盘上,使得每行,每列,每条对角线(包括两条主对角线的所有对角线)上都至多有一个棋子. 列号 0 1 2 3 4 5 6 ...
- mysql You can't specify target table 'xxx' for update in FROM clause
含义:您不能在子句中为更新指定目标表'xxx'. 错误描述:删除语句中直接含select,如下: DELETE FROM meriadianannotation WHERE SeriesID IN ( ...
- Right-BICEP单元测试
一.测试方法:Right-BICEP Right-结果是否正确? B-是否所有的边界条件都是正确的? I-能查一下反向关联吗? C-能用其他手段交叉检查一下结果吗? E-你是否可以强制错误条件发生? ...
- Android开发第二阶段(4)
今天:对按扭位置重新调整了一下布局了一下,改变了layout中见面的字体格式等等是其更美观. 明天:对图片的修改和替换.
- Transparent Flow Migration for NFV
Transparent Flow Migration for NFV 摘要 因为SDN提供的灵活性,NF之间存在着流量的迁入和迁出问题.而且NF也要根据相关的状态信息处理数据包,所以流量迁移必须满足以 ...
- 第二章 script元素
<script>元素 async:可选.表示应该立即下载脚本,但不应妨碍页面中的其他操作,比如下载其他资源或等待加载其他脚本.只对外部脚本文件有效. charset:可选.表示通过 ...
- iOS- 指压即达,如何集成iOS9里的3D Touch
1.前言 随着6S的到来,3DTouch被各大热门APP迅速普及,博主亲自体验后,发现使用便捷性大幅提高,随后自己照着文档,写了个Demo出来,分享给大家,希望能对有需要的朋友提供有一些帮助. 2 ...
- 详解Python闭包,装饰器及类装饰器
在项目开发中,总会遇到在原代码的基础上添加额外的功能模块,原有的代码也许是很久以前所写,为了添加新功能的代码块,您一般还得重新熟悉源代码,稍微搞清楚一点它的逻辑,这无疑是一件特别头疼的事情.今天我们介 ...
- react-router之代码分离
概念 无需用户下载整个应用之后才能访问访问它.即边访问边下载.因此我们设计一个组件<Bundle>当用户导航到它是来动态加载组件. import loadSomething from 'b ...