DispatchQueue 同步并发

Sah*_*Roy 4 grand-central-dispatch ios swift

好吧,我已经经历了大量的问题和答案,并且我知道对其的理解,但是当我尝试一些代码时,我得到的结果并不支持这些理论。

到目前为止我所理解的:

  1. 同步:一旦块内的所有任务都被执行,控制就会返回。
  2. 异步:控制将在块被击中后立即返回。

这是看起来不错的部分。现在是棘手的部分

  1. Serial :任务将在块内以串行方式执行。Q1:这适用于块内的任务吗?因为它已经在所有场景中发生。同样对于同步串行队列,在不同的块中添加任务并不重要,因为一旦第一个任务完成,控制就会返回。

例如-

 let syncQ = DispatchQueue(label:"xyz") // by default it is serial
  syncQ.sync{
      for _ in 0...10{
          print("ABC")
      }
  }

  syncQ.sync{
      for _ in 0...10{
          print("XYZ")
      }
  }
Run Code Online (Sandbox Code Playgroud)

预期输出:ABC * 10,XYZ * 10 这很好。

现在,当我引入并发串行 Q 时,输出是相同的。所以我的问题是,正如并发队列所说,任务将同时或同时完成,但它并没有发生。

例如-

let syncConc = DispatchQueue(label:"con",attributes:.concurrent)
syncConc.sync{
       for _ in 0...10{
          print("XYZ")
       }

       for _ in 0...10{
          print("ABC")
       }

}


  syncConc.sync{
       for _ in 0...10{
          print("HHH")
       }

       for _ in 0...10{
          print("XXX")
       }

}
Run Code Online (Sandbox Code Playgroud)

输出:XYZ*10、ABC*10、HHH*10、XXX*10

因此,同步并发队列的行为就像串行队列一样,进行并发操作的唯一方法是我们在操作之间抛出一个异步队列。所以从这里我无法理解,并发类型的串行队列的目的是什么。

如果有人可以提供编码示例,我将不胜感激,因为我已经知道它的理论和工作原理。非常感激。

Kar*_*tor 12

问题在于您混淆了队列类型和执行模型。

\n

有串行队列和并发队列,您可以同步或异步将任务分派给这两种类型。

\n

队列可以是:

\n
    \n
  • 串行 -> 一次仅执行一项任务
  • \n
  • 并发 -> 可以同时运行多个任务
  • \n
\n

我们可以将任务提交到队列中:

\n
    \n
  • 同步 -> 调用者需要等待任务返回
  • \n
  • 异步 -> 调用者代码无需等待任务完成即可重新获得控制权
  • \n
\n

把它们加起来:

\n
    \n
  • 队列的串行或并发类型决定了它是否可以同时执行一个或多个任务
  • \n
  • 同步或异步调度任务确定调用者\xe2\x80\x99s代码何时重新获得控制权
  • \n
\n


imD*_*per 6

实际上,在您的代码中,当您在并发队列(第二个片段)中执行任务时,您正在通过同步块分派任务,因此这将根据同步行为阻塞当前线程。

\n\n

“同步:一旦块内的所有任务都被执行,控制权就会返回。\xe2\x80\x9d

\n\n
   let syncConc = DispatchQueue(label:"con",attributes:.concurrent)\n\n   syncConc.sync{\n      for _ in 0...10{\n        print("XYZ")\n      }\n\n      for _ in 0...10{\n        print("ABC")\n      }\n   }\n\n\n   syncConc.sync{\n      for _ in 0...10{\n        print("HHH")\n      }\n\n      for _ in 0...10{\n        print("XXX")\n      }\n   }\n
Run Code Online (Sandbox Code Playgroud)\n\n

因此,在这种情况下,首先 suncConc 队列将调度第一个同步块,现在由于它是阻塞调用,因此下一个任务不会立即调度,它将被调度,一旦第一个任务完成,然后它将被调度在 suncConc 队列中分派并再次通过阻塞调用执行。

\n\n

现在,让我来回答您的问题

\n\n

“现在,当我引入并发串行 Q 时,输出是相同的。所以我的问题是,正如并发队列所说,任务将同时或同时完成,但它并没有发生。”

\n\n

是的,同步操作也可以同时执行,但只有当您立即分派两个调用而不阻塞当前线程时才有可能。检查下面的代码片段,两个同步任务是从不同的队列调度的,因此它将同时执行。

\n\n
    let syncConc = DispatchQueue(label:"con",attributes:.concurrent)\n\n\n    DispatchQueue.global(qos: .utility).async {\n        syncConc.sync{\n            for _ in 0...10{\n                print("XYZ - \\(Thread.current)")\n            }\n            for _ in 0...10{\n                print("ABC - \\(Thread.current)")\n            }\n        }\n    }\n\n\n    DispatchQueue.global(qos: .userInitiated).async {\n        syncConc.sync{\n            for _ in 0...10{\n                print("HHH - \\(Thread.current)")\n            }\n\n            for _ in 0...10{\n                print("XXX - \\(Thread.current)")\n            }\n        }\n    }\n
Run Code Online (Sandbox Code Playgroud)\n\n

执行代码并查看所有理论将按预期应用的魔力:)

\n