Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference in approach to create DispatchQueue Swift3

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

what is the difference how to create dispatch queue

sample 1

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

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

sample 2

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

as far as I understand this two approaches do the same

or for example this approach

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

what does it mean?

like image 714
Aleksey Timoshchenko Avatar asked Feb 04 '17 15:02

Aleksey Timoshchenko


People also ask

How do you create a serial queue?

serial when creating a serial queue: let serialQueue = DispatchQueue(label: "queuename") . In Xcode 8 beta 4 there is no . serial option so you have to create serial queue by omitting the . concurrent in attributes.

Is DispatchQueue serial or concurrent?

A dispatch queue that is bound to the app's main thread and executes tasks serially on that thread. A dispatch queue that executes tasks concurrently using threads from the global thread pool. A dispatch queue that executes tasks serially in first-in, first-out (FIFO) order.

Is DispatchQueue global serial or concurrent?

The main dispatch queue is a globally available serial queue executing tasks on the application's main thread.

What do we use DispatchQueue for?

A dispatch queue executes tasks serially or concurrently on its associated thread. If you want to read more about dispatch queues, I encourage you to read my article Concurrent vs Serial DispatchQueue: Concurrency in Swift explained.


1 Answers

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.


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.

like image 90
Rob Avatar answered Sep 28 '22 08:09

Rob