0
点赞
收藏
分享

微信扫一扫

linux 异步I/O 信号

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​​

http代理服务器(3-4-7层代理)-网络事件库公共组件、内核kernel驱动 摄像头驱动 tcpip网络协议栈、netfilter、bridge 好像看过!!!! 但行好事 莫问前程 --身高体重180的胖子

举报

相关推荐

0 条评论