Matrix
Matrix

Reputation: 7623

How current queue, dispatch queue and target queue communicates with each other in GCD?

I was following blogs, online articles, videos for GCD, and I come across a term target queue(on some of the blogs). I thought I understood GCD, but then this target queue terminology really confused me.

What I understood is:

For example:

viewdidload(){
       DispatchQueue.main.async{
          print("hello world")
       }
}

Upvotes: 2

Views: 1259

Answers (2)

Xavier Chia
Xavier Chia

Reputation: 257

Rob is completely correct.

From Apple Docs:

Redirects all blocks from the current dispatch queue to the specified target queue. Use target queues to redirect work from several different queues onto a single queue. You might do this to minimize the total number of threads your app uses, while still preserving the execution semantics you need.

Here is a code snippet as an example you can run on Playgrounds. In the example below, all print statements will run from the same thread. If you remove the target: T parameter, you will have three separate threads.

let t = DispatchQueue(label: "T")

// try removing the target parameter to see the difference in thread
let a = DispatchQueue(label: "A", attributes: .concurrent, target: t)
let b = DispatchQueue(label: "B", target: t)

a.async {
    for num in 1...5 {
        print("\(num) \(Thread.current)")
    }
}

a.async {
    for num in 6...10 {
        print("\(num) \(Thread.current)")
    }
}

b.async {
    for num in 20...24 {
        print("\(num) \(Thread.current)")
    }
}

Personally, the reason why I believe this is an advanced topic is because you won't face this problem till much later where you have too many queues. (1) In such a scenario where you are creating too many threads, slowing down the system. You want to reduce the number of threads. (2) Another reason, as Rob pointed out, is you have three serial queues, and you really want them all to run in serial to each other.

As such, this is more of a refactoring tool after you've created too many queues and (1) want to better manage them and (2) manually refactoring the queues might mean changing hundreds to thousands of lines of code.

Upvotes: 0

Rob
Rob

Reputation: 438212

A target queue is a somewhat advanced topic that isn’t used very often. Unless you have very specific needs (see below), you can safely ignore this feature.

When you create a custom queue, you can define it to have a target, a queue that your custom queue will use behind the scenes. So if you create a queue, A, with a target queue, T, then anything dispatched to A will actually run on T. So, you might ask when one might be inclined to use this pattern:

  1. Perhaps you have several queues that you want to share some behavior. For example, you might have queues A, B, and C that all are using serial queue T as their target. Then, not only will A, B, and C be serial, individually, but across A, B, and C, too. E.g. dispatch something to A and another thing to queue B, the task on B will wait for the task on A to finish (because of the serial nature of T, their shared target queue).

    Or imagine that you have three concurrent queues, A, B, and C, but you occasionally want to do a barrier across all three, some critical task that cannot run concurrently with respect to anything running on those three queues. If, when you creating A, B, and C, you specified concurrent queue T to be the target queue for all of them, if you add a barrier task to T, then A, B, and C will all honor that barrier.

  2. You might use target queues if you profile your code and you discover that you have a very high number of “context switches” taking place where your GCD code is resulting in constant jumping between different threads. For common GCD applications (e.g. run this computationally expensive code on some background queue, and then dispatch the update back to the main queue), this target queue concept offers no practical benefit. But if you’re doing thousands/millions of dispatches between GCD queues, it might be relevant. But profile your code before you bother, to detect how many context switches are happening and see if this will offer any practical benefit in your scenario.

    For examples of where you might use target queues for these performance related issues, see WWDC 2017 video Modernizing Grand Central Dispatch Usage: Introducing Unified Queue Identity. In the above link, I’ve tried to drop you off in the relevant portion of the video, but watching the whole video might offer greater context.

Bottom line, there are cases where you might need to specify a target queue, but it’s pretty uncommon in practice.

Upvotes: 10

Related Questions