【问题标题】:Python select() consumes 100% CPUPython select() 消耗 100% CPU
【发布时间】:2019-03-04 16:42:58
【问题描述】:

我正在尝试创建一个应用程序,该应用程序创建一个套接字并在传入数据出现在套接字时打印它们。 select is the preferred method to work with sockets 所以我写了这个:

#!/usr/bin/python3

from select import select
import socket

s = 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 uncommented

s.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 reaching 100% usage with select in python,但没有清楚解释为什么需要某种睡眠。

【问题讨论】:

  • 不确定是否重复,但此页面上的答案可能会有所帮助 - stackoverflow.com/questions/17431690/…
  • 很可能您的select 会立即返回,因为您的套接字总是准备好写入。
  • 您正在将s 添加到“写入”选择器列表中,但没有进行任何写入。因此,select 总是立即返回并准备好写入。不要选择你实际上没有做的操作
  • 但是,“某种睡眠”本来就是这里的答案; time.sleep(0.1)。如果您不打算在循环中写入,请不要将您的套接字放在 writer 列表中(它几乎随时都可以写入)。
  • 如果您有一些数据要尽快在该套接字上发送,您应该只在您的 write-selectors-list 中包含一个套接字,因此需要select() 在有空间时立即返回在该套接字的输出缓冲区中保存它。

标签: python sockets


【解决方案1】:

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

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

另一种可能性是在某处添加time.sleep(0.02),例如。 G。当您在该循环中不做任何其他事情时。然后,20 毫秒的额外延迟应该不会有什么坏处(但是,它并不干净)。

【讨论】:

    【解决方案2】:

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

    while True:
        readers, writers, err = select([s], [], [])
        if s in readers:
            data = s.recv(1024)
            print(data)
    

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-01-26
      • 1970-01-01
      • 1970-01-01
      • 2012-09-25
      • 2016-10-27
      • 2021-11-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多