检查何时使用非阻塞打开发送所有数据
如果我以 os.open( '/dev/ttyS2', O_RDWR | O_NDELAY ) 打开一个文件,有什么方法可以检查我的 'write()' 命令何时完成?或者,我可以打开一个文件进行非阻塞读取但阻塞写入吗?
If I open a a file as os.open( '/dev/ttyS2', O_RDWR | O_NDELAY )
, is there any way that I can check when my 'write()' commands have finished? Or, can I open a file for non-blocking read but blocking write?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
您对非阻塞的含义有误解。它不暗示异步操作 - 您可以使用异步/同步和阻塞/非阻塞的任意组合。
write() 只是将数据交给内核来处理。当 write() 成功返回时,内核现在已经处理了数据 - 无论文件描述符是阻塞还是非阻塞,都是如此。此时内核是否真正完成写入是另一回事(通常答案是“否” - 大多数文件描述符都是异步的)。
如果内核没有更多空间来缓冲要写入的数据,则 write() 无法完成,这是受非阻塞与阻塞影响的情况 - 在阻塞情况下,
write()
将阻塞,直到有可用空间。在非阻塞情况下,write()
将返回错误 (EAGAIN
),您可以稍后重试。如果您希望等到写入终端设备的所有数据实际上都已发送到硬件,请使用 tcdrain() - 但这可能是不必要的。或者,如果您希望 write() 阻塞直到内核接受数据,则可以使用 fcntl() 暂时将文件描述符设置为阻塞。
You have a misunderstanding of what non-blocking means. It does not imply asynchronous operation - you can have any combination of asynchronous/synchronous and blocking/non-blocking.
A
write()
just hands data off to the kernel to take care of. Whenwrite()
returns successfully, the kernel has now taken care of the data - this is true regardless of whether the file descriptor is blocking or non-blocking. Whether or not the kernel has actually finished writing it at this point is a separate matter (usually, the answer is "no" - most file descriptors are asynchronous).A
write()
cannot complete if the kernel has no more room to buffer the data you want to write, and this is the case that is affected by non-blocking versus blocking - in the blocking case, thewrite()
will block until space is available. In the non-blocking case,write()
will return an error (EAGAIN
), and it is up to you to retry it later.If you wish to wait until all data written to a terminal device has actually been sent to the hardware, use
tcdrain()
- but this is likely to be unnecessary. Alternatively, if you wishwrite()
to block until your data is accepted by the kernel, then you can usefcntl()
to temporarily set the file descriptor to blocking.如果您正在写入 tty(如示例中所示),则可以使用
termios.tcdrain
等待所有写入的字节都已传输。您的
write
系统调用仍然是非阻塞的,因此您需要处理EWOULDBLOCK
/EAGAIN
错误,并使用select( 2)
、poll(2)
或epoll(7)
了解何时可以写入文件描述符。这些被设计为与非阻塞文件描述符一起使用。If you are writing to a tty (as you are in your example), you can use
termios.tcdrain
to wait until all written bytes have been transmitted.Your
write
systems calls will still be non-blocking, so you will need to handleEWOULDBLOCK
/EAGAIN
errors, and useselect(2)
,poll(2)
orepoll(7)
to know when you can write to the file descriptor. These are designed to be used with non-blocking file descriptors.O_NDELAY 标志始终影响读取和写入。要实现对非阻塞文件的阻塞写入,您可以选择(Python 模块)该文件并在循环中变为可写时写入。
The O_NDELAY flag always affects both reading and writing. To achieve a blocking write on a non-blocking file you can select (Python module) the file and write when it becomes writable in a loop.
操作系统 API write() 返回写入字节数。根据输入的大小检查该值,您可以看到所有输入何时发送。
OS API write() returns count of written bytes. Checking this value against size of your input you can see when all input is sent.
在同一位置打开两个文件描述符 - 一个用于非阻塞读取,另一个用于阻塞写入。
Open two file descriptors to the same location - one for non-blocking reads and the other for blocking writes.
您尝试过 os.fsync(fd) 吗?
Have you tried
os.fsync(fd)
?