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 的套路的更多相关文章

  1. sloop公共程序之总体描述

    1:功能需求 开发一个公共库文件sloop.c,实现三个常用功能以供其它模块调用.三个功能如下: 功能一:实现一般的信号监听,调用模块只需传入要监听的信号和相应的回调函数就可以在信号到时调用回调函数处 ...

  2. python 模块初识

    python的强大之处在于有丰富的实现各种功能的标准库和第三方库,另外还允许用户自己建立库文件, 标准模块(又称为库)包括sys, os, glob, socket, threading, _thre ...

  3. 第6章 初识MyBatis

    6.1 什么是MyBatis Mybatis(前身是iBatis)是一个支持普通SQL查询.存储过程以及高级映射的持久层框架.MyBatis框架也被称为ORM(Object/Relational Ma ...

  4. 论consul正确的关闭姿势

    最近在工作中发现一个有意思的现象,我用 ctrl+c 关闭本地 consul 的时候,报警系统并没有发出告警,说我的 node 异常,自己看了一下代码,发现 consul 的关闭还是有点猫腻的,仔细来 ...

  5. python系统模块

    Python中大多数系统接口都集中在两个模块:sys和os.这么说有点过于简单化 还有一些其他的表转模块也属于这个领域他们包括: glob 用于文件名的扩展 socket 用于网络连接和进程间通信(I ...

  6. 最全的ORACLE-SQL笔记

    -- 首先,以超级管理员的身份登录oracle sqlplus sys/bjsxt as sysdba --然后,解除对scott用户的锁 alter user scott account unloc ...

  7. Matplotlib数据可视化(6):饼图与箱线图

    In [1]: from matplotlib import pyplot as plt import numpy as np import matplotlib as mpl mpl.rcParam ...

  8. Libevent学习之SocketPair实现

    Libevent设计的精化之一在于把Timer事件.Signal事件和IO事件统一集成在一个Reactor中,以统一的方式去处理这三种不同的事件,更确切的说是把Timer事件和Signal事件融合到了 ...

  9. (转载) Linux IO模式及 select、poll、epoll详解

    注:本文是对众多博客的学习和总结,可能存在理解错误.请带着怀疑的眼光,同时如果有错误希望能指出. 同步IO和异步IO,阻塞IO和非阻塞IO分别是什么,到底有什么区别?不同的人在不同的上下文下给出的答案 ...

随机推荐

  1. ES6对数组的扩展

    ECMAScript6对数组进行了扩展,为数组Array构造函数添加了from().of()等静态方法,也为数组实例添加了find().findIndex()等方法.下面一起来看一下这些方法的用法. ...

  2. PSP阶段和WBS

    项目:PSP Daily 详情请见项目功能说明书 PSP2.1 Personal Software Process Stages 预估耗时长 Planning 计划   · Estimate · 开发 ...

  3. c# webBrowser清除缓存问题

    1.webBrowser的浏览器为ie. 2.通过清除ie缓存即可. 3.代码调用如下: public enum ShowCommands : int { SW_HIDE = , SW_SHOWNOR ...

  4. WPF浏览器应用程序与JS的互调用(不用WebBrowser)

    首先说些题外话,很久没有写博客了,空间里面的大部分文章还是11年写的.那时候刚毕业就来到这家公司,参与到一个Asp.net MVC的项目开发中,这个项目是一个全新的项目,连项目开发框架都没有,亏得领导 ...

  5. keepalived 高可用(IP飘移)

    什么是keepalived? keepalived是一个在c中编写的路由软件,该项目的主要目标是为Linux系统和基于Linux的基础架构提供简单和强大的设备,用于loadbalance和高可用性.l ...

  6. C语言语法树

  7. PXE推一半失败,HP服务器、曙光服务器删除数据

    一.#设备:惠普HP DL380 Gen9 PXE安装失败,系统尝试从硬盘启动 需要将安装未完整的系统数据删除,以便正常装机 从控制台重启设备 重启后,HP在此界面选择Intelligent Prov ...

  8. HDU 2154 跳舞毯

    http://acm.hdu.edu.cn/showproblem.php?pid=2154 Problem Description 由于长期缺乏运动,小黑发现自己的身材臃肿了许多,于是他想健身,更准 ...

  9. 因为NLS_LANG 造成 Oracle数据库丢失 中文字符集兼容问题的处理.

    接着上一封blog. 因为sqlplus的 乱码问题 我修改了 注册表里面 NLS_LANG 的 value值.主要改动为: NLS_LANG source: SIMPLIFIED CHINESE_C ...

  10. (windows下的)Apache无法启动解决 the requested operation has failed

     以下文章是转载别人的,这里只做学习用 ============================================================================== ...