简体   繁体   English

在Linux中唤醒阻塞串口读取

[英]Wake up blocking serial port read in Linux

I use the select() call to indefinitely block on a serial port fd in a dedicated thread that constantly reads data. 我使用select()调用无限期地阻塞不断读取数据的专用线程中的串行端口fd。 I can't figure out a way to wake up from my select call though (unless I set a timeout, etc). 我找不到从我的选择呼叫中醒来的方法(除非我设置超时等)。 In sockets programming you have the shutdown() call to wake up any threads blocked on select(). 在套接字编程中,您可以通过shutdown()调用来唤醒select()上阻塞的任何线程。

With serial ports though, I don't see any analogue. 虽然有串口,我看不到任何模拟。 Calling close() from another thread while my 'reader' thread is blocked on select() doesn't seem to be well defined behavior on POSIX. 当我的'reader'线程在select()上被阻塞时,从另一个线程调用close()似乎在POSIX上没有明确定义的行为。 On Linux specifically, calling close() on an fd will not wake up any threads that have called select() on that fd. 特别是在Linux上,在fd上调用close()不会唤醒任何在该fd上调用select()的线程。 From ( http://linux.die.net/man/2/select ): 来自( http://linux.die.net/man/2/select ):

If a file descriptor being monitored by select() is closed in another thread, the result is unspecified. 如果select()监视的文件描述符在另一个线程中关闭,则结果未指定。 On some UNIX systems, select() unblocks and returns, with an indication that the file descriptor is ready (a subsequent I/O operation will likely fail with an error, unless another the file descriptor reopened between the time select() returned and the I/O operations was performed). 在某些UNIX系统上,select()取消阻塞并返回,并指示文件描述符已就绪(后续I / O操作可能会因错误而失败,除非另一个文件描述符在返回的时间select()和执行了I / O操作)。 On Linux (and some other systems), closing the file descriptor in another thread has no effect on select(). 在Linux(以及其他一些系统)上,关闭另一个线程中的文件描述符对select()没有影响。 In summary, any application that relies on a particular behavior in this scenario must be considered buggy. 总之,任何依赖于此场景中特定行为的应用程序都必须被视为错误。

Is it possible to wake up a thread blocked indefinitely on a serial port fd in Linux, and if so, how? 是否有可能在Linux上的串口fd上无限期地唤醒一个被阻塞的线程,若然,怎么办?

edit: 编辑:

There's a 'hack'-ish way to get around this by calling select() in a loop with sleep() (this isn't ideal though since now there's a delay between a wakeup request and the thread actually waking up). 通过在sleep()循环中调用select()来解决这个问题有一种“黑客”方法(虽然现在唤醒请求和实际唤醒的线程之间存在延迟)但这并不理想。 Is there anything detrimental about calling select in a loop system wise? 在循环系统中明智地调用select有什么不利吗?

Two typical solutions: 两种典型解决方案

  1. Create pipe and add it to select queue. 创建管道并将其添加到选择队列。 As soon as you send data over this pipe - select exits. 只要您通过此管道发送数据 - 选择退出。

  2. If waking all threads is not a problem, you can send a signal. 如果唤醒所有线程不是问题,您可以发送信号。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM