Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

priority of Dispatch Queues in swift 3

Tags:

swift

I have read the tutorial about GCD and Dispatch Queue in Swift 3

But I'm really confused about the order of synchronous execution and asynchronous execution and main queue and background queue.

I know that if we use sync then we execute them one after the precious one, if we use async then we can use QoS to set their priority, but how about this case?

func queuesWithQoS() {
    let queue1 = DispatchQueue(label: "com.appcoda.myqueue1")
    let queue2 = DispatchQueue(label: "com.appcoda.myqueue2")

    for i in 1000..<1005 {
                print(i)
    }


    queue1.async {
        for i in 0..<5{
            print(i)
        }
    }

    queue2.sync {
        for i in 100..<105{
            print( i)
        }
    }
}

enter image description here

The outcome shows that we ignore the asynchronous execution. I know queue2 should be completed before queue1 since it's synchronous execution but why we ignore the asynchronous execution and what is the actual difference between async, sync and so-called main queue?

like image 231
user7341005 Avatar asked Mar 26 '17 06:03

user7341005


People also ask

What is dispatch queue in Swift?

Dispatch queues are FIFO queues to which your application can submit tasks in the form of block objects. Dispatch queues execute tasks either serially or concurrently. Work submitted to dispatch queues executes on a pool of threads managed by the system.

How many types of dispatch queues are there?

There are two types of dispatch queues, serial dispatch queues and concurrent dispatch queues.

Is DispatchQueue main concurrent?

In general, dispatch queues will only perform one task at a time in a first-in, first-out kind of fashion. They can, however, be configured to schedule work concurrently. The main dispatch queue is a queue that runs one task at a time.

Is DispatchQueue global concurrent?

You can make use of the global concurrent queue as follows: DispatchQueue. global(). async { /// Concurrently execute a task using the global concurrent queue.


3 Answers

You say:

The outcome shows that we ignore the asynchronous execution. ...

No, it just means that you didn't give the asynchronously dispatched code enough time to get started.

I know queue2 should be completed before queue1 since it's synchronous execution ...

First, queue2 might not complete before queue1. It just happens to. Make queue2 do something much slower (e.g. loop through a few thousand iterations rather than just five) and you'll see that queue1 can actually run concurrently with respect to what's on queue2. It just takes a few milliseconds to get going and the stuff on your very simple queue2 is finishing before the stuff on queue1 gets a chance to start.

Second, this behavior is not technically because it's synchronous execution. It's just that async takes a few milliseconds to get it's stuff running on some worker thread, whereas the synchronous call, because of optimizations that I won't bore you with, gets started more quickly.

but why we ignore the asynchronous execution ...

We don't "ignore" it. It just takes a few milliseconds to get started.

and what is the actual difference between async, sync and so-called main queue?

"Async" merely means that the current thread may carry on and not wait for the dispatched code to run on some other thread. "Sync" means that the current thread should wait for the dispatched code to finish.

The "main thread" is a different topic and simply refers to the primary thread that is created for driving your UI. In practice, the main thread is where most of your code runs, basically running everything except that which you manually dispatch to some background queue (or code that is dispatched there for you, e.g. URLSession completion handlers).

like image 71
Rob Avatar answered Oct 16 '22 16:10

Rob


sync and async are related to the same thread / queue. To see the difference please run this code:

func queuesWithQoS() {
    let queue1 = DispatchQueue(label: "com.appcoda.myqueue1")

    queue1.async {
        for i in 0..<5{
            print(i)
        }
    }
    print("finished")

    queue1.sync {
        for i in 0..<5{
            print(i)
        }
    }
    print("finished")
}

enter image description here

The main queue is the thread the entire user interface (UI) runs on.

like image 39
vadian Avatar answered Oct 16 '22 18:10

vadian


First of all I prefer to use the term "delayed" instead of "ignored" about the code execution, because all your code in your question is executed.

QoS is an enum, the first class means the highest priority, the last one the lowest priority, when you don't specify any priority you have a queue with default priority and default is in the middle:

  • userInteractive
  • userInitiated
  • default
  • utility
  • background
  • unspecified

Said that, you have two synchronous for-in loops and one async, where the priority is based by the position of the loops and the kind of the queues (sync/async) in the code because here we have 3 different queues (following the instructions about your link queuesWithQoS() could be launched in viewDidAppearso we can suppose is in the main queue)

The code show the creation of two queues with default priority, so the sequence of the execution will be:

  1. the for-in loop with 1000..<1005 in the main queue
  2. the synchronous queue2 with default priority
  3. the asynchronous queue1 (not ignored, simply delayed) with default priority

Main queue have always the highest priority where all the UI instructions are executed.

like image 42
Alessandro Ornano Avatar answered Oct 16 '22 18:10

Alessandro Ornano