10

在用于串行通信的多线程 Linux 程序中,是否可以(以及最好的方法)终止来自另一个线程的阻塞 read() 调用?

我希望尽可能保持一切反应,并避免使用任何超时重复轮询。

这个问题的背景是我正在尝试使用 JNI 为 Linux 创建一个 Scala 串行通信库。我试图使本机端尽可能简单,提供 read() 和 close() 函数等。在 Scala 方面,一个线程会调用 read() 并阻塞,直到来自串行端口的数据可用。但是,可以通过其他方式关闭串口,从而调用 close()。现在,要释放阻塞的线程,我需要以某种方式取消系统读取调用。

4

3 回答 3

17

一个相当流行的技巧:不是在 read() 中阻塞,而是在串行套接字和管道上的 select() 中阻塞。然后,当另一个线程想要唤醒您的线程时,它可以通过向该管道的另一端写入一个字节来实现。该字节将导致 select() 返回,您的线程现在可以清理并退出或任何它需要做的事情。(请注意,为了使这项工作 100% 可靠,您可能希望将串行套接字设置为非阻塞,以确保您的线程仅在 select() 中阻塞,而从不在 read() 中阻塞)

于 2013-05-19T19:54:49.407 回答
4

AFAIK 信号是使任何线程脱离阻塞系统调用的唯一方法。

使用pthread_kill()针对带有 USR1 信号的线程。

于 2013-05-19T17:22:46.320 回答
1

你可能会做假数据输入:

tty_ioctl(fd,TIOCSTI,"please unblock!");

在调用它之前,您应该设置一些全局标志,以便能够在 'read(...)' 返回后检查接收到的数据是否只是唤醒 goo 或更重要的东西。

来源:https ://www.systutorials.com/docs/linux/man/4-tty_ioctl/

于 2018-03-13T20:57:48.620 回答