如何打断一个电话?

Pet*_*uin 6 c linux interrupt fread

我有以下情况:

有一个线程从具有fread调用的设备读取.只要没有数据从设备发送,此呼叫就会被阻止.当我停止这个线程时,它仍然挂在这个线程内.

现在我在fread的手册页中找到了以下内容:

错误

在符合Single UNIX Specification的所有系统上,fread()函数将errno设置为以下条件:

[EINTR]由于接收到信号而终止了读取操作,并且没有传输数据.

这意味着有一种方法可以中断来自不同线程的调用.但我不知道怎么做.有人能告诉我如何发送信号来中断这个电话吗?我需要发出什么信号?


更新08-10-10 09:25

我还没有工作.我用不同的信号尝试了kill()和pthread_kill().但似乎没有什么能打断fread()调用.我唯一能做的就是杀死整个应用程序,但这不是我想要的.

sle*_*ica 9

1.信号:

正如许多其他人指出的那样,使用信号会起作用.然而,正如许多其他人也指出的那样,这种方法有其缺点.

2.选择():

使用select()(或其他多路复用功能),可以阻止等待数据从多个文件描述符到达,并指定超时.

使用超时对您有利.每当select()返回时,检查一个全局变量以查看是否必须终止.如果你想立即反应,继续阅读.

3.选择()和管道:

多个fds意味着您可以等待通过您提到的设备到达的数据,例如管道.

在创建线程之前,创建一个管道,然后让select()上的线程块监视设备和管道.无论何时要取消阻止选择设备是否有新数据,都要向管道发送一个字节.

如果select()告诉您由于数据通过管道到达而解除阻塞,则可以清理并终止.请注意,此方法比信令方法更灵活,因为除了使用管道作为唤醒方法之外,您还可以使用它来传递有用的信息或命令.

4.选择(),管道和信号:

如果您使用多个进程并且不希望/不能传递管道,则可以组合这两个解决方案.创建一个管道并为SIGUSR1安装一个信号处理程序.在信号处理程序中,沿管道发送一个字节.

每当进程发送SIGUSR1时,将调用该处理程序并取消阻塞select().通过检查fdsets,您将知道除了您自己的程序发出信号之外没有其他原因.


Pla*_*ure 3

看一眼man 2 kill。(或者看这里

不过,我感觉你不想这样做——大多数时候人们会忽略 errnoEINTR并再次阅读。您可能想研究一下非阻塞读取。

  • 除了使用“kill”从另一个线程生成信号之外,“alarm”函数还经常用于导致阻塞的“read”调用超时。 (2认同)