暂停和恢复 Grand Central Dispatch 线程

Posted

技术标签:

【中文标题】暂停和恢复 Grand Central Dispatch 线程【英文标题】:Suspending and resuming Grand Central Dispatch thread 【发布时间】:2014-03-26 05:15:08 【问题描述】:

我正在使用 Grand Central Dispatch 在后台运行进程。我想知道如何暂停、恢复和停止该后台线程。我试过了

dispatch_suspend(background_thread);
dispatch_resume(background_thread);

但这些功能对我没有帮助,它继续运行。请有人帮助我。

【问题讨论】:

如果实现这种方式比使用 NSOperation 而不是 GCD 更好。使用 NSOperation,您可以更轻松地实现这一点,这也将使您免于许多多线程复杂性和问题。 但是为什么上面的GCD功能不起作用? @CRDave,你能给我一个 NSOperationQueue 的例子吗?我试过这个 NSOperation *Queue = [NSOperation new]; NSInvocationOperation *op = [[NSInvocationOperation alloc]initWithTarget:self 选择器:@selector(somefun) object:@"hello"]; [队列添加操作:op];现在我想在单击按钮时暂停操作,现在请告诉我应该使用什么功能来暂停操作 那么有没有其他方法可以暂停正在运行的线程呢? 或者有什么方法可以停止GCD线程? 【参考方案1】:

你似乎有些困惑。线程的直接操作不是 GCD API 的一部分。您通常操作的 GCD 对象是队列,而不是线程。您将块放入队列中,然后 GCD 在它想要的任何线程上运行这些块。1

此外,the dispatch_suspend man page 说:

调度框架总是在执行一个块之前检查暂停状态,但是这样的改变在执行过程中永远不会影响一个块(非抢占式)。

换句话说,当队列正在运行一个块时,GCD 不会挂起队列。它只会在队列处于块之间时挂起队列。

我不知道有任何公共 API 可以让您在不与该线程上运行的函数合作的情况下停止线程(例如,通过设置在该线程上定期检查的标志)。

如果可能,您应该分解长时间运行的计算,以便您可以在连续的块中逐步处理它。然后您可以暂停运行这些块的队列。


脚注 1. 主队列除外。如果你在主队列上放一个块,GCD 只会在主线程上运行那个块。

【讨论】:

【参考方案2】:

您正在描述一种并发处理模型,其中可以暂停和恢复不同的进程。这通常使用线程或在某些情况下使用协程来实现。

GCD 使用不同的模型,即部分有序块之一,其中每个块按顺序执行,不直接支持抢占、暂停或恢复。

GCD 信号量确实存在,并且可能满足您的需求,但是使用它们创建通用的协作并发线程并不是 GCD 的目标。否则,请查看使用 NSThread 甚至 Posix 线程的基于线程的解决方案。

查看 Apple 的 Migrating Away from Threads,看看您的模型是否适合迁移到 GCD,但并非所有模型都适合。

【讨论】:

以上是关于暂停和恢复 Grand Central Dispatch 线程的主要内容,如果未能解决你的问题,请参考以下文章

NSOperation 与 Grand Central Dispatch

Grand Central Dispatch 用于复杂流程?

iOS多线程编程之Grand Central Dispatch(GCD)介绍和使用

Swift - 多线程实现方式 - Grand Central Dispatch(GCD)

Grand Central Dispatch (GCD) 与 performSelector - 需要更好的解释

swift Grand Central Dispatch(GCD)发送信号量示例