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分别是什么,到底有什么区别?不同的人在不同的上下文下给出的答案 ...
随机推荐
- Nginx特性验证-反向代理/负载均衡/页面缓存/URL重定向
原文发表于cu:2016-08-25 参考文档: Nginx 反向代理.负载均衡.页面缓存.URL重写等:http://freeloda.blog.51cto.com/2033581/1288553 ...
- asp之GetArray提取链接地址,以$Array$分隔的代码
'================================================== '函数名:GetArray '作 用:提取链接地址,以$Array$分隔 '参 数:ConStr ...
- 冲刺ing-5
第五次Scrum冲刺 队员完成的任务 队员 完成任务 吴伟华 Leangoo的看板截图,燃尽图 蔺皓雯 编写博客 蔡晨旸 测试 曾茜 测试 鲁婧楠 测试 杨池宇 测试 成员遇到的问题 队员 问题 吴伟 ...
- 《JavaScript》JS中的常用方法attr(),splice()
1.jquery中用attr()方法来获取和设置元素属性,attr是attribute(属性)的缩写,在jQuery DOM操作中会经常用到attr(),attr()有4个表达式. attr(属性名) ...
- OOP 1.4 内联函数和重载函数函数参数缺省值
1.内联函数 存在的背景:函数调用存在开销(调用时候参数压栈,返回地址压栈:返回时从栈取出返回地址,跳转到返回地址.总共需要几条指令的开销).如果函数指令较少,调用多次,函数调用的开销占比大. 内联函 ...
- (Miller Rabin算法)判断一个数是否为素数
1.约定 x%y为x取模y,即x除以y所得的余数,当x<y时,x%y=x,所有取模的运算对象都为整数. x^y表示x的y次方.乘方运算的优先级高于乘除和取模,加减的优先级最低. 见到x^y/z这 ...
- Websphere Application Server 环境配置与应用部署最佳实践
在发布一个运行于 WebSphere Application Server 的 J2EE 应用之前,对服务器进行配置和部署应用是必不可少的一个过程,这个过程是非常复杂的.WAS 为用户提供了可视化的管 ...
- [学习]WireShark 的过滤功能
1. 打开 wireShark 过滤显示 协议 比如显示arp协议 过滤栏输入arp即可 支持的协议类型 TCP UDP HTTP FTP ICMP SMTP等等 2. 过滤ip地址 ip.addr ...
- PHP对象的遍历
对象的遍历 对象的遍历,跟数组的遍历,一样! 其实,只能遍历出对象的“实例属性数据” foreach( $对象名 as $key => $value){ //这里就可以处理$key和$va ...
- HttpClient出现大量time_wait问题
在高并发短连接的TCP服务器上,当服务器处理完请求后立刻主动正常关闭连接.这个场景下会出现大量socket处于TIME_WAIT状态.如果客户端的并发量持续很高,此时部分客户端就会显示连接不上.我来解 ...