Unix套接字中异步和非阻塞的区别是什么?

21

我在nginx中看到了这样的代码:

if(fcntl(ngx_processes[s].channel[0], F_SETFL, fcntl(s, F_GETFL) | O_NONBLOCK) == -1) {
...
if (ioctl(ngx_processes[s].channel[0], FIOASYNC, &on) == -1) {
...

有人能告诉我 fcntl(s, F_SETFL, fcntl(s, F_GETFL) | O_NONBLOCK)ioctl(s, FIOASYNC, &on) 之间的区别吗?难道 asyncnonblocking 不是同样的东西吗?


2
+1你的一系列问题教会了我要远离nginx :-) - R.. GitHub STOP HELPING ICE
1个回答

23

FIOASYNC切换文件描述符的O_ASYNC标志(通常在open(2)fcntl(2)中设置),请求内核在文件描述符准备好进行IO时向进程发送SIGIOSIGPOLL信号。

O_ASYNC并不经常使用:

  • 在信号处理程序中正确处理IO非常困难,最好让它们尽可能小
  • 因为信号中断程序的控制流,所以它们比标准系统调用(例如select(2)poll(2))运行“更昂贵”。
  • 相比其他调用,信号提供的信息较少:它们只报告一个fd已经准备好,而不是可能准备好的多个fds。

O_NONBLOCK对用户进程没有任何通知,表明文件描述符已经准备好进行read(2)write(2)操作——相反,它改变了read(2)write(2)等调用的行为,如果文件描述符没有准备好进行读取或写入,则立即返回。 O_NONBLOCK通常与select(2)poll(2)类似调用一起使用,以确保客户端或服务器的主循环不会阻塞在一个特定的对等体上,从而使所有其它对等体"饿死"。


另外,FIOASYNC是一种完全非标准/遗留的方法,用于使用openfcntl执行与O_ASYNC等效的操作。 - R.. GitHub STOP HELPING ICE
5
不,异步和非阻塞是完全不同的概念。 - R.. GitHub STOP HELPING ICE
1
@cpuer:设置标志可能有很好的理由,但应该使用符合标准的方式来进行设置,即使用带有O_ASYNCfcntl,而不是一些古老的类似于1980年代的ioctl - R.. GitHub STOP HELPING ICE
@R..,你能描述一下ASYNC回调函数被调用的情况吗?它会阻塞原始进程例程吗? - cpuer
@R:您能引用指定 fcntlO_ASYNC(或者提到 O_ASYNC)的标准吗? - Nemo
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接