【发布时间】:2017-04-09 13:50:16
【问题描述】:
今天我尝试了以下代码:
- (void)suspendTest {
dispatch_queue_attr_t attr = dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_CONCURRENT, QOS_CLASS_BACKGROUND, 0);
dispatch_queue_t suspendableQueue = dispatch_queue_create("test", attr);
for (int i = 0; i <= 10000; i++) {
dispatch_async(suspendableQueue, ^{
NSLog(@"%d", i);
});
if (i == 5000) {
dispatch_suspend(suspendableQueue);
}
}
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(6 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
NSLog(@"Show must go on!");
dispatch_resume(suspendableQueue);
});
}
代码启动了 10001 个任务,但它应该暂停队列中途运行新任务,以便在 6 秒后恢复。此代码按预期工作 - 执行了 5000 个任务,然后队列停止,6 秒后它恢复。 但是如果我使用串行队列而不是并发队列,那么我的行为就不清楚了。
dispatch_queue_attr_t attr = dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_BACKGROUND, 0);
在这种情况下,随机数量的任务在挂起之前设法执行,但通常这个数字接近于零(挂起发生在任何任务之前)。 问题是 - 为什么挂起串行队列和并发队列的工作方式不同以及如何正确挂起串行队列?
【问题讨论】:
-
您发布的代码无法编译。您的
if (i == 5000) {行位于for循环之后。 -
我的错,我只是凭记忆复制了它。让我解决它
-
好的,这是您不将真实代码粘贴到浏览器中的问题之一?我不能落后。
-
@matt 我是根据我在办公室拍的照片写的。只是一个错字:)
-
让我问你这个问题:你为什么期待任何东西?无法保证队列何时开始,特别是考虑到它是
QOS_CLASS_BACKGROUND。所以你不是说串行队列从未启动吗?为什么这是一个惊喜,因为没有关于它的规则? 尤其是,因为您占用了主队列,这可能会使后台队列更不愿意开始?毕竟,实际的线程管理不取决于我们;这就是GCD的point。
标签: ios objective-c grand-central-dispatch