Objective c 使用串行端口上的read()操作取消线程

Objective c 使用串行端口上的read()操作取消线程,objective-c,c,multithreading,serial-port,Objective C,C,Multithreading,Serial Port,在Cocoa项目中,我与连接到串行端口的设备通信。现在,我正在等待串行设备发送一些字节的特定消息。对于读取操作(以及收到所需消息后的反应),我创建了一个新线程。根据用户请求,我希望能够取消线程 正如Apple在中所建议的,我在线程字典中添加了一个标志,定期检查该标志是否已设置,如果已设置,请调用[NSThread exit]。这个很好用 现在,线程可能会被困在等待串行设备最终发送12字节的消息。read调用如下所示: numBytes = read(fileDescriptor, buffer,

在Cocoa项目中,我与连接到串行端口的设备通信。现在,我正在等待串行设备发送一些字节的特定消息。对于读取操作(以及收到所需消息后的反应),我创建了一个新线程。根据用户请求,我希望能够取消线程

正如Apple在中所建议的,我在线程字典中添加了一个标志,定期检查该标志是否已设置,如果已设置,请调用
[NSThread exit]
。这个很好用

现在,线程可能会被困在等待串行设备最终发送12字节的消息。read调用如下所示:

numBytes = read(fileDescriptor, buffer, 12);
一旦线程开始从设备读取数据,但没有数据进入,我可以设置标志告诉线程完成,但线程不会读取标志,除非它最终接收到至少12字节的数据并继续处理

有没有办法杀死当前在串行设备上执行读取操作的线程

编辑以澄清: 我不坚持为串行设备的I/O操作创建单独的线程。如果有一种方法可以封装这些操作,这样,如果用户按下取消按钮,我就可以“杀死”它们,那么我非常高兴。 我正在为桌面Mac OS X开发一个Cocoa应用程序,因此对移动设备及其功能没有任何限制。 一种解决方法是,如果没有要读取的字节,则使read函数立即返回。如何执行此操作?

使用或超时来检测描述符何时准备好读取

将超时设置为(比如)半秒,并在循环中调用它,同时检查线程是否应该退出


异步线程取消几乎总是一个坏主意。尝试使用事件驱动的接口(如果需要,还有超时)。

这正是
pthread\u cancel
接口的设计目的。您需要在
pthread\u cleanup\u push
中使用
read
pthread\u cleanup\u pop
包装该块,以便在线程被取消时可以安全地进行清理,并且在不希望取消的该线程中运行的其他代码中禁用取消(使用
pthread\u setcancelstate
)。如果适当的清理会涉及多个调用帧,这可能是一个痛苦;它基本上迫使您在每个调用级别使用<代码> pthRead java CuffuxPux/Cuth>并使用C++代码或Java来构造线程代码,使用<代码>尝试/<代码> catch < /Cord>样式异常处理。 另一种方法是为其他未使用的信号(如
SIGUSR1
或其中一个实时信号)安装一个信号处理程序,而不使用
sau RESTART
标志,以便它使用
EINTR
中断系统调用。信号处理器本身可以是一个完全不可操作的处理器;它的唯一目的是打断事情。然后可以使用
pthread\u kill
中断特定线程中的
读取(或任何其他系统调用)。这样做的好处是,您不必将代码转换为使用C++/Java类型的习惯用法。您可以通过检查标志(指示线程是否被请求中止)来处理
EINTR
错误,如果未设置该标志,则恢复读取,或者返回导致调用方清除并最终退出
pthread\u
的错误代码


如果您确实使用中断信号处理程序,请确保可以返回
EINTR
的所有系统调用都包装在循环中,这些循环在
EINTR
上重试(或检查中止标志并可选地重试)。否则情况可能会严重恶化。

这是一种非常糟糕的方法。您不应该编写经常唤醒并轮询变量的应用程序。这会破坏电池寿命,听起来OP是为移动设备写的,这是一个大问题。。。您可以通过在
select
/
poll
调用中添加管道,并通过管道发送中止请求,从而达到消除超时/唤醒的相同效果。我正在为桌面Mac OS X开发,因此没有移动设备限制。这是一种非常非常糟糕的方法。使用信号和
EINTR
会创建不可避免的争用条件,因为信号可能在线程进入read()之前传递。因此,读取不会被中断,并将永远阻塞,但只有在竞争条件触发时。。。使缺陷极难复制和修复。轮询几乎是无限可取的。(也就是说,我同意最好的答案是在select/poll中添加一个管道。)在OP想要的交互使用中,“永远阻止”实际上是“直到用户再次按下取消按钮为止阻止”。我同意这里有一个种族条件,这可能是不寻常的修复。对于一般情况,我可以考虑一个复杂的框架,其中包含一个非平凡的信号处理程序和LongJMP,这些信号处理程序可以在不违反异步信号安全或其他UB的情况下满足要求,但这可能不是OP想要的。。。