if (ioctl(ngx_processes[s].channel[0], FIOASYNC, &on) == -1) {
ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
"ioctl(FIOASYNC) failed while spawning \"%s\"", name);
ngx_close_channel(ngx_processes[s].channel, cycle->log);
return NGX_INVALID_PID;
} if (fcntl(ngx_processes[s].channel[0], F_SETOWN, ngx_pid) == -1) {
ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
"fcntl(F_SETOWN) failed while spawning \"%s\"", name);
ngx_close_channel(ngx_processes[s].channel, cycle->log);
return NGX_INVALID_PID;
}

分析:

  • 设置channel[0]的信号驱动异步I/O标志 ,FIOASYNC:该状态标志决定是否收取针对socket的异步I/O信号(SIGIO)
  • 其与O_ASYNC文件状态标志等效,可通过fcntl的F_SETFL命令设置or清除
  • F_SETOWN:用于指定接收SIGIO和SIGURG信号的socket属主(进程ID或进程组ID) 这里意思是指定Master进程接收SIGIO和SIGURG信号 , 
  • SIGIO信号必须是在socket设置为信号驱动异步I/O才能产生,即上一步操作 SIGURG信号是在新的带外数据到达socket时产生的 

FIOASYNC toggles the O_ASYNC flag (which is usually set in open(2) or fcntl(2)) for a file descriptor, which will ask the kernel to send SIGIO or SIGPOLL to the process when the file descriptor is ready for IO.

O_ASYNC is not used often:

  • it is extremely difficult to properly handle IO in signal handlers; they are best left as tiny as possible
  • because signals interrupt the control flow of the program, they 'cost more' to run than standard system calls, such as select(2) or poll(2)
  • signals provide less information than other calls: they only report one fd ready vs many fds that might be ready.

The O_NONBLOCK doesn't provide any notification to the user process that a fd is ready for read(2) or write(2) -- instead, it changes the behavior of read(2) and write(2) and similar calls to return immediately if the file descriptor isn't ready for reading or writing. O_NONBLOCK is typically used in conjunction with select(2) or poll(2) or similar calls to guarantee that the main loop of a client or server won't block on one specific peer, and thus starve all its peers.

ioctl和FIOASYNC等价于fcntl和O_ASYNC

ioctl和FIONBIO等价于fcntl和O_NONBLOCK

FIOASYNC设置O_ASYNC标记,该标记决定fd可以IO时进程是否会收到SIGIO和SIGPOLL信号。

FIONBIO设置O_NONBLOCK标记,该标记会改变read,write和同类函数的行为,使得在fd还不能IO时立即返回而不是hang住。

后者经常跟select,poll等函数一起使用,使得主程序不会因为个别socket而影响其他。

一般来说使用select和poll结合非阻塞的文件指针可以对应大部分情况,但是某些时候 需要使用异步的文件指针。比如:如果一个函数处理数据,但是处理时间很长,在其处理的时候 我们需要运行这个函数的进程及时响应网络事件或者内核信号,这时就需要将其置为异步

对于socket来说,如果需要设置异步的话需要三个步骤

  1. 必须注册一个响应SIGIO的信号回调函数
  2. 通过fcntl设置F_SETOWN,使得socket属于某个进程
  3. 通过fcntl设置O——ASYNC将该socket设置为异步

https://stackoverflow.com/questions/6260114/whats-the-difference-between-async-and-nonblocking-in-unix-socket

https://stackoverflow.com/questions/7440571/whats-the-difference-between-fionbio-and-fioasync-for-socket

linux 异步I/O 信号的更多相关文章

  1. linux 异步信号的同步处理方式

    关于代码的可重入性,设计开发人员一般只考虑到线程安全,异步信号处理函数的安全却往往被忽略.本文首先介绍如何编写安全的异步信号处理函数:然后举例说明在多线程应用中如何构建模型让异步信号在指定的线程中以同 ...

  2. arm驱动linux异步通知与异步IO【转】

    转自:http://blog.csdn.net/chinazhangzhong123/article/details/51638793 <[ arm驱动] linux异步通知与 异步IO> ...

  3. Linux异步IO【转】

    转自:http://blog.chinaunix.net/uid-24567872-id-87676.html Linux® 中最常用的输入/输出(I/O)模型是同步 I/O.在这个模型中,当请求发出 ...

  4. Linux环境进程间通信(二): 信号(上)

    linux下进程间通信的几种主要手段: 管道(Pipe)及有名管道(named pipe):管道可用于具有亲缘关系进程间的通信,有名管道克服了管道没有名字的限制,因此,除具有管道所具有的功能外,它还允 ...

  5. linux异步IO--aio

    简述 linux下异步方式有两种:异步通知和异步IO(AIO),异步通知请参考:linux异步通知 Linux的I/O机制经历了一下几个阶段的演进: 1. 同步阻塞I/O: 用户进程进行I/O操作,一 ...

  6. linux系统编程之信号(一):中断与信号

    一,什么是中断? 1.中断的基本概念 中断是指计算机在执行期间,系统内发生任何非寻常的或非预期的急需处理事件,使得CPU暂时中断当前正在执行的程序而转去执行相应的事件处理程序,待处理完毕后又返回原来被 ...

  7. linux异步通知

    简述 linux下异步方式有两种:异步通知和异步IO(AIO),aio请参考:linux异步IO--aio 异步通知的含义是:一旦设备就绪,则主动通知应用程序,这样应用程序就不需要查询设备状态,准确称 ...

  8. Linux异步IO操作

    Linux® 中最常用的输入/输出(I/O)模型是同步 I/O.在这个模型中,当请求发出之后,应用程序就会阻塞,直到请求满足为止.这是很好的一种解决方案,因为调用应用程序在等待 I/O 请求完成时不需 ...

  9. Linux进程间通信--进程,信号,管道,消息队列,信号量,共享内存

    Linux进程间通信--进程,信号,管道,消息队列,信号量,共享内存 参考:<linux编程从入门到精通>,<Linux C程序设计大全>,<unix环境高级编程> ...

随机推荐

  1. JavaWeb01_html&css

    一. html简介 1. 什么是html ①. HyperText Markup Language:超文本标记语言,是最基本的网页语言 ②. 超文本:超出文本范畴 ③. 标记:标记就是标签,html所 ...

  2. 串口wifi

    串口wifi 串口WiFi ZLAN7146是一款wifi转串口的wifi串口服务器.该串口服务器可以方便地使得串口设备连接到WIFI无线网络,实现串口设备的无线化网络升级.RS232接口支持全双工. ...

  3. rabbitmq 交换机模式一 直连模式 direct

    代码 <?php require_once "./vendor/autoload.php"; use PhpAmqpLib\Connection\AMQPStreamConn ...

  4. rabbitmq 延时队列

    前言 某个产品 或者订单,有个有效期 过了有效期要取消 方法一 : 写个脚本,用crontab 定时扫描 改变状态 但是最低只能一分钟 ,不适合 方法二 : 用swoole得毫秒定时器,每秒钟去扫描表 ...

  5. go 加锁

    package mainimport ( "fmt" "math/rand" "sync" "time")var tic ...

  6. VIM 批量注释的两种方法 (转)

    方法一 ctrl+v 进入列编辑模式,向下或向上移动光标,把需要注释的行的开头标记起来,然后按大写的I(shift+i),再插入注释符,比如"//",再按Esc,就会全部注释了 批 ...

  7. linux创建www用户组和用户

    linux创建www用户组和用户 wdcp中的nginx服务启动需要依赖www用户,因此若没有此用户就可能会启动失败.创建这个用户的方法: [root@bogon local]# id www [ro ...

  8. <!DOCTYPE>,<address>,<applet>的用法

    希望以下内容能让大家有所收获 HTML <!DOCTYPE> 标签 实例 <!DOCTYPE html> <html> <head> <title ...

  9. js实现无缝连接轮播图(二)实现自定义属性,根据banner图片的数量动态生成小圆点

    <!-- 这个animate.js 必须写到 index.js的上面引入 --><script src="js/animate.js"></scrip ...

  10. 安卓日常开发和逆向中常用的shell命令与非shell命令

    简述shell 命令与 非shell命令区别 shell命令不用先adb shell进入界面执行 非shell命令必须要 adb shell进入界面执行 基础非shell命令 1.安装app adb ...