创建DispatchQueue Swift3的方法有什么区别

创建DispatchQueue Swift3的方法有什么区别

问题描述:

我是Swift中的新秀,并且有这样的误解

I am a rookie in Swift, and there is such misunderstandings

创建调度队列有什么区别

what is the difference how to create dispatch queue

样本1

let backgroundQueue = DispatchQueue(label: "com.app.queue",
                                qos: .background, 
                                target: nil)

backgroundQueue.async {
print("Dispatched to background queue")
}

样本2

let backgroundQueue = DispatchQueue.global()
backgroundQueue.async {
print("Dispatched to background queue")
}

据我了解,这两种方法的作用相同

as far as I understand this two approaches do the same

或者例如这种方法

DispatchQueue.global(qos: .userInitiated).async {
print("user initiated task")
}

是什么意思?

在第一个示例中创建的队列是您自己的自定义串行队列.如过时但仍然相关,

The queue you create in your first example is your own custom serial queue. As the somewhat dated, yet still relevant, Concurrency Programming Guide says:

串行队列(也称为私有调度队列)按照将它们添加到队列中的顺序一次执行一个任务.当前正在执行的任务在分派队列管理的不同线程(随任务的不同而不同)上运行.串行队列通常用于同步对特定资源的访问.

Serial queues (also known as private dispatch queues) execute one task at a time in the order in which they are added to the queue. The currently executing task runs on a distinct thread (which can vary from task to task) that is managed by the dispatch queue. Serial queues are often used to synchronize access to a specific resource.

您可以根据需要创建任意数量的串行队列,并且每个队列相对于所有其他队列可以同时运行.换句话说,如果您创建四个串行队列,则每个队列一次只能执行一个任务,但仍然最多可以同时执行四个任务,每个队列一个.

You can create as many serial queues as you need, and each queue operates concurrently with respect to all other queues. In other words, if you create four serial queues, each queue executes only one task at a time but up to four tasks could still execute concurrently, one from each queue.

后面的示例仅使用检索系统提供的并发全局队列:

Whereas your latter examples are using simply retrieving system-provided global queues which are concurrent:

并发队列(也称为全局调度队列的一种)同时执行一个或多个任务,但是任务仍然按照它们添加到队列中的顺序启动.当前执行的任务在分派队列管理的不同线程上运行.在任何给定时间执行的确切任务数是可变的,并取决于系统条件.

Concurrent queues (also known as a type of global dispatch queue) execute one or more tasks concurrently, but tasks are still started in the order in which they were added to the queue. The currently executing tasks run on distinct threads that are managed by the dispatch queue. The exact number of tasks executing at any given point is variable and depends on system conditions.

现在,您现在可以创建自己的自定义并发队列,但是全局队列只是为我们创建的并发队列.

Now, you can nowadays create your own custom concurrent queue, but a global queue is simply a concurrent queue that was created for us.

那么,这对您意味着什么?

So, what does this mean to you?

  • 如果将块分配到串行队列(第一个示例),则任何时候都只能运行一个块.这对于在多线程应用程序中同步内存访问非常有用,但可以在需要后台队列但希望调度的块相对于该队列中的其他块串行(即顺序)运行的任何环境中使用

  • If you dispatch blocks to serial queue (your first example), only one block can run at any time. This makes it really useful for synchronizing memory access in multi-threaded apps, but can be used in any environment where you need a background queue, but you want dispatched blocks to be run serially (i.e. sequentially) with respect to other blocks on that queue.

在后面的示例中使用的全局队列是并发队列.这意味着,如果您向该全局队列分派四个单独的任务,则这些块可能会相对于彼此并发运行.这是理想的选择,您不仅真正希望后台执行,而且不在乎这些块是否也与其他调度块同时运行.

The global queues that you are using in your latter examples are concurrent queues. This means that if you dispatch four separate tasks to this global queue, those blocks may run concurrently with respect to each other). This is ideal where you really want not only background execution, but don't care if these blocks also run at the same time as other dispatched blocks, too.

在后面的示例中,当您访问全局队列时,请认识到由于这些是系统提供的,因此与这些队列的交互有一些适度的限制,即:

In your latter examples, where you're accessing a global queue, recognize that because those are system-provided, you have some modest limitations on your interaction with these queues, namely:

  • 您不能暂停全局队列;

  • You cannot suspend global queues;

您不能在全局队列上使用障碍;

You cannot use barriers on global queues;
 

但是,尽管如此,如果您只是在寻找一种简单的方式来调度要在后台运行的块(并且您不关心这些已调度的块是否在同一时间同时运行),则全局队列是非常简单有效的方法.

But, with that notwithstanding, if you are just looking for an simple way of dispatching blocks to run in the background (and you don't care if those dispatched blocks run at the same time as each other), then global queues are incredibly simple and efficient way to do that.

顺便说一句,第二个示例(我假设您打算使用let backgroundQueue = DispatchQueue.global())和第三个示例之间的区别只是在第三个示例中,您分配了显式的服务质量(qos),而在第三个示例中,您分配了显式的服务质量(qos).第二个示例,您使用的是默认的qos. FWIW,通常建议指定一个qos,以便OS可以相应地优先考虑争夺有限系统资源的线程.

By the way, the difference between your second example (for which I assume you intended let backgroundQueue = DispatchQueue.global()) and the third example, is merely that in your third example, you assigned the explicit quality of service (qos), whereas in your second example, you're using the default qos. FWIW, it's generally advisable to specify a qos, so that the OS can prioritize threads contending for limited system resources accordingly.