打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
nginx中的阻塞和非阻塞设置

纵然对于select,epoll这2个模型,既可以使用阻塞模式的socket也可以使用非阻塞的

虽然,但是这2个模型的消息通知可以防止accetp,recv在阻塞模式下的进入阻塞状态,却不能防止NGINX主动发出的connect和send进入阻塞状态


特别是NGINX是单线程模型,任何调用的阻塞状态都会造成整个线程阻塞甚至挂起,这对NGINX来说是完全不能接受的


因此在ngx_open_listening_sockets函数中,对所有listen socket,除非是IOCP或者UNIX_AIO模型,都把这个socket设置成非阻塞模式,代码如下:

            if (!(ngx_event_flags & NGX_USE_AIO_EVENT)) {
                if (ngx_nonblocking(s) == -1) {
                    ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
                                  ngx_nonblocking_n ' %V failed',
                                  &ls[i].addr_text);


                    if (ngx_close_socket(s) == -1) {
                        ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
                                      ngx_close_socket_n ' %V failed',
                                      &ls[i].addr_text);
                    }


                    return NGX_ERROR;
                }
            }

而在ngx_event_accept中,也有一样的实现逻辑

        /* set a blocking mode for aio and non-blocking mode for others */


        if (ngx_inherited_nonblocking) {
            if (ngx_event_flags & NGX_USE_AIO_EVENT) {
                if (ngx_blocking(s) == -1) {
                    ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_socket_errno,
                                  ngx_blocking_n ' failed');
                    ngx_close_accepted_connection(c);
                    return;
                }
            }


        } else {
            if (!(ngx_event_flags & (NGX_USE_AIO_EVENT|NGX_USE_RTSIG_EVENT))) {
                if (ngx_nonblocking(s) == -1) {
                    ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_socket_errno,
                                  ngx_nonblocking_n ' failed');
                    ngx_close_accepted_connection(c);
                    return;
                }
            }
        }


比较特殊的是connect,unix平台的传统的做法都是让connect的socket进入非阻塞模式,NGINX也是这样,在ngx_event_connect_peer中,直接设置成非阻塞模式了事

    if (ngx_nonblocking(s) == -1) {
        ngx_log_error(NGX_LOG_ALERT, pc->log, ngx_socket_errno,
                      ngx_nonblocking_n ' failed');


        goto failed;
    }


另外补充一点,win平台上的WsaAysncSelect以及WsaEventSelect会自动把套接口设置成非阻塞模式,因此不管connect,send,accept,recv都是非阻塞模式,并且有各自对应的通知消息类型


本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
nginx 0.8.x稳定版对linux aio的支持 | pagefault
nginx中upstream的设计和实现(二)
Linux中的EAGAIN含义
BOA代码笔记 3
linux非阻塞的socket EAGAIN的错误处理
非阻塞模式下connect的使用方式
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服