Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/328.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
python-select.select()如何工作? 背景:_Python_Select - Fatal编程技术网

python-select.select()如何工作? 背景:

python-select.select()如何工作? 背景:,python,select,Python,Select,我熟悉C的选择功能。我使用这个函数有很多目的。大多数(如果不是全部的话)用于读取和写入管道、文件等。我必须说,我从未使用过错误列表,但这并不涉及关键问题 问题: Python的select是否有如下行为 在我看来,Python上的select的行为方式与C select的接口不同。似乎select会在文件第一次准备好读取时返回。如果您在读取文件的同时保留一些要读取的字节,则调用select将阻塞。但是,如果在返回上一个select调用后再次调用select,而这两个调用之间没有任何read调用,

我熟悉C的选择功能。我使用这个函数有很多目的。大多数(如果不是全部的话)用于读取和写入管道、文件等。我必须说,我从未使用过错误列表,但这并不涉及关键问题

问题: Python的select是否有如下行为

在我看来,Python上的select的行为方式与C select的接口不同。似乎select会在文件第一次准备好读取时返回。如果您在读取文件的同时保留一些要读取的字节,则调用select将阻塞。但是,如果在返回上一个select调用后再次调用select,而这两个调用之间没有任何read调用,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文档所说的:如果read | write | error列表中的任何文件准备好了read | write | error,select就会返回。。没关系,那里没有谎言。也许问题应该是:

当文件被认为可以在python中读取时? 它是指一个从未被读取过的文件吗? 这是否意味着要读取包含字节的文件? 正如您所期望的,Python的select作为select系统调用传递,但它的阻塞问题是另一个问题,可能与缓冲有关。为了让自己确信select做的是正确的事情,尝试在文件系统上读/写文件,而不是使用特殊设备,如操纵杆

你可能想改变你的开放通话。Pythons调用默认情况下将使用缓冲读取,因此即使执行read8,它也可能从输入文件读取更多数据并缓冲结果。您需要将缓冲选项设置为打开,以便操纵杆设备在无缓冲的情况下打开

建议您尝试:

Python默认以文本模式打开文件。在处理诸如操纵杆之类的特殊设备时,您可能希望打开模式为rb。 以无缓冲模式打开文件。 如果要进行基于选择的呼叫,请将设备设置为非阻塞模式。尝试使用os.open和os.O| RDONLY | os.O|非块标志。
我可以问一个愚蠢的问题吗?你确定还有8个字节吗


设备节点的行为不一定像普通文件。可能您必须在单个读取系统调用中读取整个struct input_事件。如果你读得不够多,其余的都会被扔掉。有点像数据报套接字上的recvmsg。

@user799204,这是一个多么愚蠢的问题?你看过这些声明了吗?是的,我确信这是一个例子。让你知道这一点的唯一方法是,如果你愿意,试一下自己。以下步骤是插入操纵杆,同时按下两个按钮。如果在同一时间生成事件,则select将返回。发出file.read8并再次调用select查看我为什么开始这个问题。哦,顺便说一句,8是特定事件的字节大小。但是如果您愿意,您可以使用小于队列中字节总数的任何数量。看到公认的答案,缓冲是个问题。为我拙劣的措辞道歉。我的意思是我的问题可能很愚蠢。它显示了。结构输入\事件仅适用于事件文件。你的8字节是struct js_事件的正确大小。我没意见,编辑也很好。我只想提一下您对UDP数据包的看法:您是在谈论数据包丢失吗?UDP就是这样,它没有控制传输。我不认为有人编写的驱动程序中数据“可能”以不确定的方式丢失。或者,您正在谈论的是一个队列已满的问题。如果您的设备队列已满,旧事件将替换为新事件,因此是的,您可能会以这种方式丢失数据。无论如何,这不是问题所在。您好。我想知道您的阅读尺寸是否太小了。如果您天真地从UDP读取了8个字节,而数据包是16个字节,那么最后8个字节将丢失,这反映在MSG_TRUNC标志中。使用0缓冲区大小调用open可以做到这一点,这对我来说是有意义的。无需将文件描述符设置为非阻塞,也无需更改读取模式。这样更好,因为在阅读之后,需要将字符串解压到一个结构中。