NSTask可以安全地在主线程之外使用吗?

时间:2010-06-12 19:37:37

标签: cocoa thread-safety nsthread nstask

昨天我read somewhere that NSTask isn't thread safe这让我很烦恼,因为我在NSThread中运行NSTask,到目前为止还没有遇到任何线程问题。

我的代码是这样组织的

A: main thread -> B: worker thread -> C: worker task

C: The worker task is a commandline program.
B: The worker thread can start/stop the worker task and send it commands.
A: The main thread can send commands to the worker thread.

如果NSTask应该仅在主线程中使用,那么我正在考虑将NSTask启动/停止代码移动到主线程,以防止可能的线程问题。

可以在主线程之外使用NSTask吗?

如果没有,那么NSTask的线程问题可能是什么?

2 个答案:

答案 0 :(得分:4)

  

read somewhere that NSTask isn't thread safe ...

这不是那个页面所说的。它表示你将在你启动它的同一个线程上获得进程终止通知,这表明NSTask知道线程并尝试做正确的事情。

该页面的编辑之一遇到的问题是他们从一个线程开始他们的进程,然后让线程死掉。这导致了崩溃,因为框架不再能够将流程终止的通知传递给正确的线程。

Thread Safety Summary(书签)说出类似的内容,将NSTask列在一个类的列表中:

  

在大多数情况下,只要您一次只使用一个线程,就可以从任何线程使用这些类。查看课程文档以获取更多详细信息。

NSTask文档没有说明任何关于线程的内容,因此听起来像NSTask是“大多数情况”之一:您可以使用您创建它的线程中的任务。不要在另一个线程上使用相同的任务,并且(如上所述)确保线程的持续时间至少与任务进程一样长。

但是,我会注意到,在大多数情况下,不需要在单独的线程上运行任务。与进程中的其他线程一样,单独的进程倾向于在其他处理器上运行,并且运行循环可以很好地复用许多小事件并保持UI响应。如果需要读取任务的输出,可以使用NSFileHandle's readInBackgroundAndNotify method。您可以完全删除工作线程。

另一种选择是,正如Eimantas建议的那样,使用NSOperation:有一个简单地启动特定任务并等待该任务退出的操作(可能同步读取它的输出)。任务退出后,操作即完成。

答案 1 :(得分:0)

是的,可以,但我建议您使用NSOperation。它是KVO不可知的(与线程NSTask不同)。您也可以查看有关KVO和线程环境的接待员设计模式(如果您需要KVO)。