2

假设我有 2 个线程,一个是主线程,另一个是辅助线程。主线程使用最多,但有时(很少)我希望辅助线程根据来自主线程的调用做一些工作。大多数时候辅助线程应该休眠。现在经过一番搜索,我明白做到这一点的方法是使用 runLoops。所以我尝试阅读苹果的文档(http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/Multithreading/RunLoopManagement/RunLoopManagement.html#//apple_ref/doc/uid/10000057i-CH16-SW5 )

但在我看来它非常复杂,我在那里度过了一段艰难的时光。有没有一种优雅而简单的方法来实现我所描述的?我可以运行和玩任何类似的 runLoop 代码示例吗?

谢谢

4

3 回答 3

5

每个线程都有一个运行循环。

每个运行循环都有一个需要完成的事情的列表。据说这些事情是在运行循环中“安排的”,尽管并非所有事情都安排在特定的日期和时间:

  • 计时器是。
  • 来源不是。他们通常会等待某个东西敲响 Mach 内核端口或文件描述符。

当运行循环运行时,它通常没有运行——也就是说,线程正在休眠,不消耗任何 CPU 周期。(如果您对其进行采样,您会发现该进程似乎卡在mach_msg_trap. 这是“等待某事发生”系统调用。)内核唤醒线程(从而从mach_msg_trap)当某些事情发生时碰巧线程的运行循环需要处理。

完全按照您的描述进行操作的方法是实现run loop source。您将源安排在辅助线程的运行循环上,通过工作来实现它,并在有工作要做时从主线程发出信号。

但是, NSOperation 几乎可以肯定是一个更好的解决方案,因为它是为您描述的情况而设计的:需要连续完成的离散工作单元,一次最多 N(您选择并且至少为 1)。

请注意 NSOperationQueue 重用线程,因此它不一定为每个操作创建一个新线程。事实上,不这样做是重点的一部分:它懒惰地创建线程,并使用它已经拥有的任何不做任何事情的线程。

于 2010-09-22T21:29:12.020 回答
4

这听起来就像NSOperation/NSOperationQueue的用途。如果你只有偶尔的“工作单元”,为什么不让它们成为一个操作,然后监视它的完成并相应地更新你的 UI?

于 2010-09-22T14:25:31.670 回答
2

Matt Gallagher 有一篇不错的博客文章,将辅助线程方法与其他完成后台工作的方法进行了比较。

http://cocoawithlove.com/2010/09/overhead-of-spawning-threads.html

在您的情况下,您不必担心线程创建开销。但是,Matt 的代码示例可能会为管理辅助线程的 runloop 提供一些见解。

综上所述,我会听从 Joshua 的建议,只使用 NSOperationQueue 和 NSOperation 来完成后台工作。如果可以将工作封装在 NSInvocation 中,则可以使用 NSInvocationOperation 并避免使用 NSOperation 子类。

于 2010-09-22T16:06:20.417 回答