如何异步“打开”和“关闭”串口?
How to `open` and `close` a serial port asynchronously?
我正在尝试以异步方式使用串口。我可以使用 select
、poll
或 epoll
和 O_NONBLOCK
来进行异步读写。但是 open
和 close
呢?
我看到 close
阻塞超过一秒。
很少有操作系统实现真正的异步 open()
和 close()
(将 O_NONBLOCK
指定为 open()
意味着不要等待连接或输入,实际上并没有真正在后台执行操作)。想到的两个是 QNX 和 Hurd,它们都是微内核操作系统设计,根据定义,每个系统调用都是可复用的,因此是异步的。
至于为什么,从历史上看,在 open()
完成之前你不能做任何事情,所以 API 设计者从未想过让它异步。最近,如果您真的希望它是异步的,请从线程池进行调用。 close()
更有趣一点,实际上很难在不丢失有价值信息的情况下快速关闭文件描述符,丢失这些信息会导致数据丢失,例如"the buffered data I just tried to write out failed"。但同样,如果你真的需要 close()
异步,只需从线程池中调用它即可。
一般来说,如果你经常调用 open()
和 close()
,你就不能期待高性能。两者都不可避免地涉及使内核 运行 进行大量代码检查权限、分配内核结构、锁定内核结构等。通常对于高性能文件 i/o 例如,您在开始并且永远不要关闭它们。这在大多数操作系统上都表现出色。
我正在尝试以异步方式使用串口。我可以使用 select
、poll
或 epoll
和 O_NONBLOCK
来进行异步读写。但是 open
和 close
呢?
我看到 close
阻塞超过一秒。
很少有操作系统实现真正的异步 open()
和 close()
(将 O_NONBLOCK
指定为 open()
意味着不要等待连接或输入,实际上并没有真正在后台执行操作)。想到的两个是 QNX 和 Hurd,它们都是微内核操作系统设计,根据定义,每个系统调用都是可复用的,因此是异步的。
至于为什么,从历史上看,在 open()
完成之前你不能做任何事情,所以 API 设计者从未想过让它异步。最近,如果您真的希望它是异步的,请从线程池进行调用。 close()
更有趣一点,实际上很难在不丢失有价值信息的情况下快速关闭文件描述符,丢失这些信息会导致数据丢失,例如"the buffered data I just tried to write out failed"。但同样,如果你真的需要 close()
异步,只需从线程池中调用它即可。
一般来说,如果你经常调用 open()
和 close()
,你就不能期待高性能。两者都不可避免地涉及使内核 运行 进行大量代码检查权限、分配内核结构、锁定内核结构等。通常对于高性能文件 i/o 例如,您在开始并且永远不要关闭它们。这在大多数操作系统上都表现出色。