2017-02-08 32 views
1

当我运行下面的操场我注意到默认调度队列似乎是叫OS_dispatch_queue_serial一个串行队列Swift 3:为什么OS_dispatch_queue_serial是默认队列?

这是为什么?

在这种情况下,我对异步同步语义使用混乱,在这种情况下,他们似乎是同步和连续行为。

我错了吗? 我在混淆与同步的连续?

enter image description here

运行代码之前我期待实现如下:

Hello World 
Hello Moon 

world * (or Moon) 
Moon * (or world) 
// Note: here I assumed that async meant that the codes in the block would have been run in parallel to each other and that this would have meant that either world or Moon would have been printed depending on **race conditions** 

Hello World 
world 
Hello Moon 
Moon 

游乐场代码:

import Foundation 
import PlaygroundSupport 

PlaygroundPage.current.needsIndefiniteExecution = true 

let queue = DispatchQueue(label: "com.test.myqueue") 

queue.async { 
    print("Hello World") 
    sleep(2) 
    print("world") 
} 
queue.async { 
    print("Hello Moon") 
    sleep(1) 
    print("Moon") 
} 

queue.sync { 
    print("Hello World") 
    sleep(2) 
    print("world") 
} 

queue.sync { 
    print("Hello Moon") 
    sleep(1) 
    print("Moon") 
} 

任何帮助了解这更快的将是巨大的。

回答

2

您正在混淆同步与异步,串行与并行。它们是正交的。让我看看我能不能解释一下:

同步异步描述相对于排队洱排队的块的行为。

串行平行描述相对于彼此排队的块的行为。

串行队列一次执行一个排入其中的块。无论块是同步还是异步排队,情况都是如此。

并行队列一次执行排入队列的事物N,其中N可能(但不一定)大于1.无论块是同步队列还是异步队列,这都是真的。

如果同步排队块,排队线程将停止,直到块的执行完成(可能在另一个线程上)。无论队列是串行还是并行,情况都是如此。

如果排队块异步,入队线程继续,块执行(最有可能在另一个线程)后的一定时间,可能同时入队的线程上的代码仍然在运行。无论队列是串行还是并行,情况都是如此。

至于为什么serial是默认的,很难说,但我的猜测是,这是因为'串行队列'更符合单词'queue'的字典定义。

+1

最初(的iOS 4/OS X 10.6),你不能在GCD创建并发队列。有系统并发队列,但你不能再创建。在iOS 4.3/OS X 10.7中,他们添加了创建并发队列的功能,但将串行队列保留为默认队列。在实践中,我通常很少发现有用的定制并发队列,通常在实现生产者/消费者模式时(https://github.com/iosptl/ios7ptl/blob/master/ch23-AdvGCD/ProducerConsumer/ProducerConsumer/ViewController.m) 。系统通常就足够了。通常当你制作一个自定义队列时,就是序列化访问。 –

+1

(即使我列出的例子并不需要一个自定义的并发队列;对于其中一个系统队列来说也没有问题,所以它比以前更少见:D但是很多使用串行队列的东西都是不可信的如果串行队列使用FIFO和非串行队列(并发)使用随机执行标准,那么将无法完成定制任务。) –

2

队列有两种形式:

  • 串行 - 运行在一个时间块一个
  • 并发 - 运行块一次一个

调度块队列超过有两种口味:

  • 同步 - 立即执行此操作我将等待
  • 异步 - 稍后再进行一段时间。

所以在你的例子中你创建了一个串行队列(一次只能运行一个块)。然后你将4个块分派给那个队列。其中一些运行在某个点(异步)和一些立即运行(同步)。但是因为队列是串行的,所以你一次只能运行其中的一个。因此,在下面的插图中,串行队列将在其开始块2之前完成块1.并发队列同时启动块1和块2,并且它们都在同一时间运行。

Illustration of serial vs concurrent queues

+0

因此,串行队列使用FIFO和非串行队列(并发)使用随机执行标准? (例如一小段代码块1,一小块代码块2 ..) – mm24

+0

看到我添加的图像。并发队列不交替或交错块1和2,它独立地同时执行两个块。 –