【问题标题】:Asynchronous Swift processing in Linux not workingLinux 中的异步 Swift 处理不起作用
【发布时间】:2018-07-13 19:14:51
【问题描述】:

我正在尝试了解 Swift 4.0 异步处理在 Linux 中的工作原理。

在查看了documentation 和一些answers 之后,我想出了这个简单的例子:

import Dispatch
import Glibc

DispatchQueue.main.asyncAfter(deadline: .now()) {
    print("Done!")
}

print("Sleeping for 2 seconds...")
usleep(2 * 1_000_000)

print("Exiting...")

但是,这只会打印:

Sleeping for 2 seconds...
Exiting...

为什么不打印Done!?我错过了什么?如何编写一个简单的并行处理示例?

【问题讨论】:

    标签: swift linux concurrency grand-central-dispatch swift4


    【解决方案1】:

    您必须调用dispatchMain() 来启动 GCD 事件循环:

    执行提交到主队列的块

    例子:

    DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
        print("Done!")
        exit(0)
    }
    
    print("Starting main event loop...")
    dispatchMain()
    

    【讨论】:

    • 我应该在上面的示例中将它添加到哪里?如果我在.asyncAfter{...} 之后添加它,它会打印“Done!”,但不会继续执行其他语句,也不会打印“Sleeping...”或“Exiting...”。
    • @naktinis:没错,dispatchMain 永远不会返回。你必须在某处exit(0)该程序。
    【解决方案2】:

    我认为问题在于使用main 队列。如果我改为创建一个新队列,它会按预期工作。

    import Dispatch
    import Glibc
    
    DispatchQueue(label: "worker").asyncAfter(deadline: .now()) {
        print("Doing work...")
        usleep(1 * 1_000_000)
        print("Work done")
    }
    
    print("Sleeping for 2 seconds...")
    usleep(2 * 1_000_000)
    
    print("Exiting...")
    

    打印出预期的结果:

    Sleeping for 2 seconds...
    Doing work...
    Work done!
    Exiting...
    

    【讨论】:

    • 试试asyncAfter(deadline: .now() + 4) ...那将永远不会被执行。
    【解决方案3】:

    调度不是抢先的。提交到非并发队列的块将按顺序处理,直到它们之前的块完成后才会处理任何块。你把你的块放在main队列上,它对应于主线程,但是,主线程一直忙于休眠直到它退出,并且永远没有机会做调度队列工作。

    Martin R 提到了dispatchMain,但另一个选项是RunLoop.main.run(mode: .defaultRunLoopMode, before: .distantFuture),它只会运行一次runloop,然后允许程序退出。

    【讨论】:

      猜你喜欢
      • 2016-08-21
      • 1970-01-01
      • 2021-12-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-26
      相关资源
      最近更新 更多