• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

ios - 挂起串行队列

[复制链接]
菜鸟教程小白 发表于 2022-12-12 22:39:04 | 显示全部楼层 |阅读模式 打印 上一主题 下一主题

今天我尝试了以下代码:

- (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);

在这种情况下,随机数量的任务在挂起之前设法执行,但通常这个数字接近于零(挂起发生在任何任务之前)。 问题是 - 为什么挂起对于串行队列和并发队列的工作方式不同以及如何正确挂起串行队列?



Best Answer-推荐答案


按照其名称,串行队列按顺序执行任务,即仅在前一个任务完成后从下一个任务开始。优先级是后台,所以当当前队列到达第 5000 个任务并挂起队列时,它甚至可能还没有开始第一个任务。

来自dispatch_suspend的文档:

The suspension occurs after completion of any blocks running at the time of the call.

也就是说,它没有保证队列中异步分派(dispatch)的任务会完成,只是任何当前正在运行的任务( block )都不会在中途暂停。在串行队列上最多可以有一个任务“当前正在运行”,而在并发队列上则没有指定的上限。 编辑: 根据您对一百万个任务的测试,并发队列似乎维护了它“完全并发”的概念抽象,因此即使它们实际上都认为它们“当前正在运行”不是。

要在第 5000 个任务之后暂停它,您可以从第 5000 个任务本身触发它。 (那么您可能还想从暂停时间开始启动恢复计时器,否则理论上如果恢复发生在暂停之前,它可能永远不会恢复。)

关于ios - 挂起串行队列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40184693/

回复

使用道具 举报

懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关注0

粉丝2

帖子830918

发布主题
阅读排行 更多
广告位

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap