事件驱动IO之信号驱动IO

                          事件驱动IO之信号驱动IO

接着上一篇讨论的 五种 IO 模型中 关于 事件驱动的 IO模型介绍,我们已经知道了 IO 多路复用是事件驱动的一种,接下来将继续介绍 事件驱动模型的 另外一种:信号驱动 IO

在这里插入图片描述
可以看到该模型中,只有 IO 执行到第二阶段阻塞了用户进程,而在第一阶段是没有阻塞的。
首先允许套接字进行信号驱动IO,这就意味着要设置套接字属性为 非阻塞并且异步,设置信号处理函数,进程继续运行并不阻塞。当数据准备好时,进程会收到一个 SIGIO 信号,可以在处理函数中调用 IO 操作函数处理数据。这种模型的优势在于等待数据到达(第一阶段)期间,进程可以继续执行,不被阻塞,免去了 select/epoll等多路复用方式的阻塞与轮询, 当有活跃套接字时,由注册的 hander 处理。

一、想要搞清楚 信号IO 的使用,我们需要回答好如下三个问题:

  • 什么时候会产生信号呢?
  • 产生的信号发给谁处理呢?
  • 收到信号后如何处理呢?

(1.1)首先回答一个问题,这里缩小下讨论范围,只讨论网络IO过程中信号的是啥时候产生的?
》对于 UDP 协议而言,通常会在如下 两种 情况下内核会给用户空间的用户程序发送信号:

  • 套接字收到了一个完整的数据包;
  • 套接字发生了异步错误;

当我们在使用 UDP 套接字 异步 I/O 的时候,我们使用 recvfrom() 函数来读取数据报数据或者异步IO 错误信息。

》对于 TCP 协议而言,产生信息的地方就多啦:
在 TCP 连接中, SIGIO 信号将会在这个时候产生:

  • 在一个监听某个端口的套接字上成功的建立了一个新连接;

  • 一个断线的请求被成功的初始化;

  • 一个断线的请求成功的结束;

  • 套接字的某一个通道(发送通道或是接收通道)被关闭;

  • 套接字接收到新数据;

  • 套接字将数据发送出去;

  • 发生了一个异步 I/O 的错误;

     通过对比,我们可以发现,异步 I/O 几乎对 TCP 套接字而言没有什么作用,因为对于一个 TCP 套接字来说, SIGIO 信号发生的几率太高了,所以 SIGIO 信号并不能告诉我们
    

究竟发生了什么事情。

(1.2)产生的信号发给谁处理呢?
发给谁呢?当然要发给关心 SIGIO 信号的进程啦,发给张三李四王二麻子等不相关的进程可就不对咯。这里可以通过 fcntl 系统调用的 F_SETOWN 来设置。
F_SETOWN 的含义是:设置将要在文件描述符fd 上接收 SIGIO 或 SIGURG 事件信号的进程或进程组标识。一般产生该信号后由当前进程来处理,那么我们可以如下设置:

fcntl(sockfd, F_SETOWN, getpid()); // getpid() to get current process id

(1.3)收到信号如何处理呢?
收到信号后,我们注册的信号处理函数就会去处理。这里有 signal 和 sigaction 两种方式来处理,but 强烈不推荐 signal方式(!!!)。下面我们就来看看使用 sigaction方式
是如何注册信号处理函数的。

struct sigaction sigio_action;
sigio_action.sa_flag = 0;
sigio_action.sa_handler = do_sigio; // signal hander, the same to signal's param handler
sigaction(SIGIO, &sigio_action,
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值