【问题标题】:How can I slow down a GCD concurrent queue's tasks?如何减慢 GCD 并发队列的任务?
【发布时间】:2019-08-21 10:56:24
【问题描述】:

出于性能调试的目的,每当由 GCD 并发队列操作的后台任务完成其中一项任务时,我都需要观察 UI 更新的进度。

如果没有人为的延迟,就很难跟踪和对正在发生的事情做出反应。

每个任务可能需要 10 毫秒。我喜欢花一秒钟的时间。

我尝试通过添加sleep(1); 来减慢队列的任务,但这将允许其他等待任务运行。

我需要的是每个任务确实一直占用它的队列,直到那额外的一秒结束。

如何在不重新组织整个排队代码的情况下做到这一点?毕竟,这仅用于调试,我只想插入带有条件编译的代码,而不是最终为调试和非调试构建提供不同的代码。

【问题讨论】:

  • 顺便说一句,除了像我之前描述的那样旋转之外,我发现在 Instruments 中使用“Points of Interest”对于获取视觉表示非常有用(以及关联仪器中的其他内容,例如时间分析器,分配等)。见stackoverflow.com/q/19017843/1271826

标签: macos grand-central-dispatch


【解决方案1】:

你可以旋转一段时间,例如:

func spin(for interval: CFTimeInterval) {
    let start = CACurrentMediaTime()
    while (CACurrentMediaTime() - start) < interval { }
}

所以,要让线程保持忙碌 1 秒钟,应该是:

spin(for: 1)

您永远不会在生产应用中执行此操作,但它可能有助于您的诊断目的。

【讨论】:

    【解决方案2】:

    与此同时,我还想出了一个方法,实际上与 Rob 的方法相同,通过循环消磨时间:

    mach_timebase_info_data_t tb;
    mach_timebase_info (&tb);
    double tbScale = 1.0 / (1e-9 * (double)tb.numer / (double)tb.denom);
    uint64_t now, end = mach_absolute_time();
    end += tbScale * 0.5; // -> wait 0.5 sconds
    do {
        now = mach_absolute_time();
    } while (now < end);
    

    【讨论】:

    • 是的,这行得通。 CACurrentMediaTime 是“通过调用 mach_absolute_time() 并将结果转换为秒数得出的 CFTimeInterval。”所以,这基本上是相同的想法。 ;)
    猜你喜欢
    • 2013-10-11
    • 2012-09-01
    • 2019-12-23
    • 2019-01-16
    • 2015-06-12
    • 2020-01-02
    • 1970-01-01
    • 2012-09-26
    • 1970-01-01
    相关资源
    最近更新 更多