V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
fghjghf
V2EX  ›  Python

Python epollin 的一些问题。

  •  
  •   fghjghf · 2019-04-26 23:53:28 +08:00 · 2144 次点击
    这是一个创建于 2057 天前的主题,其中的信息可能已经有所发展或是发生改变。
    情况:python3.7,epoll TCP。对端有发送数据,为啥不会触发 select.EPOLLIN ?
    然后我打印了下 epoll.poll(),fd 是没错,socket 都对得上。可是为啥 events 就对不上呢?
    发现对端发数据,events 是 5,而不是 EPOLLIN 的 4,而我把 python3.7 文档全看了一遍,都没找到 5 是对应那个宏的。
    有大佬遇到过吗,是怎么解决的
    epoll 事件如下:(这是根据官方文档打印的)
    EPOLLIN:1(int)
    EPOLLOUT:4
    EPOLLPRI:2
    EPOLLERR:8
    EPOLLHUP:16
    EPOLLET:2147483648
    EPOLLONESHOT:1073741824
    EPOLLEXCLUSIVE:268435456
    EPOLLRDHUP:8192
    EPOLLRDNORM:64
    EPOLLRDBAND:128
    EPOLLWRNORM:256
    EPOLLWRBAND:512
    EPOLLMSG:1024
    9 条回复    2019-04-27 15:01:16 +08:00
    fghjghf
        1
    fghjghf  
    OP
       2019-04-26 23:55:53 +08:00
    写错了,EPOLLIN 是 1,而不是 4
    pubby
        2
    pubby  
       2019-04-27 01:10:51 +08:00 via Android
    EPOLLIN & EPOLLOUT == 5
    weyou
        3
    weyou  
       2019-04-27 01:24:43 +08:00 via Android
    @pubby EPOLLIN | EPOLLOUT == 5
    AngryMagikarp
        4
    AngryMagikarp  
       2019-04-27 01:58:08 +08:00
    这个标志位是二进制或操作的结果,表示的就是“或”的意思。

    比如 5 = 1 | 4 = EPOLLIN | EPOLLOUT = EPOLLIN 或 EPOLLOUT

    你拿到 events 时,要判断有没有 EPOLLIN 事件,不能直接 events==EPOLLIN 判断,而要用 events & EPOLLIN 判断。表示 EPOLLIN 标志位是否已经设置,这是典型的 C 语言用法,毕竟 Python 里的 epoll 是移植自 C。

    如果你仔细观察,就会发现这些标志的二进制表示都只有一个 1。如下

    EPOLLIN: 0x00000001
    EPOLLOUT: 0x00000100
    EPOLLPRI: 0x00000010
    EPOLLERR: 0x00001000
    EPOLLHUP: 0x00010000

    也正因为如此,才能使用上述的方式将多个标志放在一个 int 里。
    AngryMagikarp
        5
    AngryMagikarp  
       2019-04-27 02:01:19 +08:00
    上面写错了,二进制应该是 0b 表示,而不是 0x。0x 表示十六进制。

    EPOLLIN | EPOLLOUT 表示

    0b00000001 | 0b00000100 = 0b00000101 = 5
    fghjghf
        6
    fghjghf  
    OP
       2019-04-27 11:41:06 +08:00
    @AngryMagikarp 感谢,我当初就是直接用 events == EPOLLIN 去判断的。
    fghjghf
        7
    fghjghf  
    OP
       2019-04-27 13:54:45 +08:00
    @AngryMagikarp 但还有个问题,对端发送 send 数据给服务端,为啥只会出发 5 呢,那肯定是谁先写,就先触发谁了,那岂不是 in 和 out 同时触发?这有什么意义呢
    AngryMagikarp
        8
    AngryMagikarp  
       2019-04-27 14:22:40 +08:00
    @fghjghf 不明白你说的先后的意思。除了 EPOLLIN 和 EPOLLOUT,你还觉得要有什么?

    正常情况下写一定是可以的,除非某些原因阻塞了。如果你要把阻塞写的逻辑也考虑进去就会比较复杂。
    fghjghf
        9
    fghjghf  
    OP
       2019-04-27 15:01:16 +08:00
    @AngryMagikarp 我这是 ET+非堵塞模式啦。看了下网上对 demo,终于懂了。原来是我是 in 和 out 一起注册了,才会老是返回 5,这是个错误的写法。应该是先注册 in,while 不断循环,直到 errno.EAGAIN。再注册 out 事件。对于 out 事件也是一样道理。感谢回答
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1367 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 17:12 · PVG 01:12 · LAX 09:12 · JFK 12:12
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.