我熟悉select()
C函数。我一直在为许多人使用这个功能。大多数(如果不是全部)读取和写入管道,文件等...我必须说我从未使用错误列表,但这不涉及关键问题。
python select()
的行为如下吗?
事实证明,尽管与select()
的{{3}}接口有关,但python上的select()
行为方式不同。似乎select()
在文件第一次准备好阅读时返回。如果您读取的文件在其队列中是字节,则调用select()
将阻止。但是,如果您在之前调用select()
之后再次呼叫select()
而未在这两次呼叫之间进行任何读取呼叫,则select()
将按预期返回。例如:
import select
# Open the file (yes, playing around with joysticks)
file = open('/dev/input/js0', 'r')
# Hold on the select() function waiting
select.select([file], [], [])
# Say 16 bytes are sent to the file, select() will return.
([<open file '/dev/input/js0', mode 'r' at 0x7ff2949c96f0>], [], [])
# Call select() again, and select() will indeed return.
select.select([file], [], [])
([<open file '/dev/input/js0', mode 'r' at 0x7ff2949c96f0>], [], [])
# read 8 bytes. There are 8 bytes left for sure. Calling again file.read(8) will empty the queue and would be pointless for this example
file.read(8)
'<\t\x06\x01\x00\x00\x81\x01'
# call select() again, and select() will block
select.select([file], [], [])
# Should it block? there are 8 bytes on the file to be read.
如果这是python中select()
的行为,我没关系,我可以处理它。不是我的预期,但它很好,我知道我能做些什么。
但是,如果这不是select()
的行为,我会很感激有人告诉我我做错了什么。我读到的关于select()
的内容是python doc所说的:“如果read | write | error列表中的任何文件都准备好读取|写入错误,则select()返回。”那没关系,没有谎言。也许问题应该是:
答案 0 :(得分:19)
Python select()
作为select()
系统调用传递,正如您所期望的那样,但是阻塞它的问题是另一个问题,可能与缓冲有关。只是为了满足自己select()
做正确的事情,尝试在文件系统上读/写文件,而不是使用操纵杆等特殊设备。
您可能想要更改open()
来电。默认情况下,Pythons open
调用将使用缓冲读取,因此即使您执行read(8)
,它也可能从输入文件中读取更多数据并缓冲结果。您需要将buffering
选项设置为open
,以便无缓冲地打开操纵杆设备。
建议您尝试:
mode
为rb
。select
的呼叫,请将设备设置为非阻止模式。尝试将os.open()
与os.O_RDONLY|os.O_NONBLOCK
标记一起使用。答案 1 :(得分:0)
我可以问一个愚蠢的问题 - 你确定还剩下8个字节吗?
设备节点不一定像普通文件一样。可能是您必须在单个read()系统调用中读取整个struct input_event。 (如果你读得不够,其余的就会被扔掉)。有点像数据报套接字上的recvmsg()。