Python的asyncio模块在create_connection时是不是同步的?
ringa_lee
ringa_lee 2017-04-17 13:17:15
[Python讨论组]

在Windows下使用asyncio模块(事件循环用的是默认的_WindowsSelectorEventLoop

探究其BaseEventLoop.create_connection的调用层次,发现其中还同步调用了connect和select函数。

首先,调用层次如下:

BaseEventLoop.create_connection
  BaseSelectorEventLoop.sock_connect
    BaseSelectorEventLoop._sock_connect
      socket.connect

然后参考socket.connect的实现,发现其中调用了connect后,还调用了select。

问题是,本来在程序等待三次握手的时候,Python可以把执行别的协程的,但是这样同步的调用,使得Python只能等待三次握手了。

这样会造成性能问题吗?

ringa_lee
ringa_lee

ringa_lee

全部回复(1)
黄舟

如果在异步上下文中调用了阻塞函数,确实会造成性能问题。不过呢,这里的 socket.connect非阻塞的,所以不会有性能问题。见 asyncio/base_events.py 393 行:

                    sock = socket.socket(family=family, type=type, proto=proto)
                    sock.setblocking(False)

这里设置了 socket 对象为非阻塞的,所以你看到的下面这些代码都会立即返回:

    res = connect(s->sock_fd, addr, addrlen);  // <<<<<<<< 1

#ifdef MS_WINDOWS

    if (s->sock_timeout > 0.0) {
        if (res < 0 && WSAGetLastError() == WSAEWOULDBLOCK &&
            IS_SELECTABLE(s)) {
            /* This is a mess.  Best solution: trust select */
            fd_set fds;
            fd_set fds_exc;
            struct timeval tv;
            tv.tv_sec = (int)s->sock_timeout;
            tv.tv_usec = (int)((s->sock_timeout - tv.tv_sec) * 1e6);
            FD_ZERO(&fds);
            FD_SET(s->sock_fd, &fds);
            FD_ZERO(&fds_exc);
            FD_SET(s->sock_fd, &fds_exc);
            res = select(Py_SAFE_DOWNCAST(s->sock_fd+1, SOCKET_T, int),
                         NULL, &fds, &fds_exc, &tv);  // <<<<<<<< 2
            if (res == 0) {
                res = WSAEWOULDBLOCK;  // <<<<<<<<<< 3
                timeout = 1;
            } else if (res > 0) {

——即使三次握手还没有完成。异步等待握手完成的代码见 asyncio/selector_events.py 的 308 行:

        except (BlockingIOError, InterruptedError): 
            self.add_writer(fd, self._sock_connect, fut, True, sock, address) 
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号