为了账号安全,请及时绑定邮箱和手机立即绑定

Python select() 占用 100% CPU

Python select() 占用 100% CPU

手掌心 2021-11-23 16:30:44
我正在尝试创建一个应用程序,该应用程序创建一个套接字并打印出现在套接字上的传入数据。select 是使用套接字的首选方法,所以我写了这个:#!/usr/bin/python3from select import selectimport sockets = socket.socket(socket.AF_INET, socket.SOCK_STREAM)s.connect(('localhost', 2345))s.setblocking(False)  # True did not change anything#s.settimeout(2)      # same behavior if uncommenteds.send(("give me data\n").encode("latin1"))while True:    readers, writers, err = select([s], [s], [])    if s in readers:        data = s.recv(1024)        print(data)    # some kind of sleep here?然而,这是代码示例消耗 100% 的一个 CPU 内核。在具有非阻塞套接字的情况下等待来自套接字的数据而没有这种无限循环的正确方法是什么?我需要它来检查连接是否仍然有效。有一个类似的问题CPU 在 python 中使用 select 达到 100% 使用率,但它没有清楚地解释为什么某种睡眠是必要的。
查看完整描述

2 回答

?
阿晨1998

TA贡献2037条经验 获得超6个赞

您调用它的方式 ( readers, writers, err = select([s], [s], [])),如果它可读或可写,它会立即返回。但是你只检查它是否可读。

由于套接字在大多数情况下可能是可写的,这正是您被告知的。

另一种可能性是在time.sleep(0.02)某处添加一个,例如,当您在该循环中不执行任何其他操作时。然后,20 毫秒的额外延迟不应该受到伤害(但是,它并不干净)。


查看完整回答
反对 回复 2021-11-23
?
缥缈止盈

TA贡献2041条经验 获得超4个赞

select 最常见的用途是只考虑rlistandtimeout参数。对于您的示例代码,它应该是:


while True:

    readers, writers, err = select([s], [], [])

    if s in readers:

        data = s.recv(1024)

        print(data)

该wlist参数仅在应用程序可能需要写入大数据时使用。在这种情况下,要写入套接字的数据只是排队,然后将套接字添加到wlist. 当select返回并且有内容要写入套接字时,程序会尝试写入,如果仍有内容,它会再次推送到队列中(注意:必须推送到头部......)并且套接字留在wlist. 如果所有内容都已写入且队列为空,则套接字将从wlist.


在上面的文本中,队列可以是真正的双端队列,也可以是简单的bytes缓冲区或任何其他允许在两端添加字节的容器。每个套接字应该存在一个。


查看完整回答
反对 回复 2021-11-23
  • 2 回答
  • 0 关注
  • 251 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信