Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GCD global queue task run on main thread

The following code

DispatchQueue.main.async {
    print(Thread.current)
    DispatchQueue.global().sync {
        print(Thread.current)
    }
}

prints

<_NSMainThread: 0x60000059c140>{number = 1, name = main}
<_NSMainThread: 0x60000059c140>{number = 1, name = main}

Technically, global queue finds an idle thread to run the task, which might be the main thread.

Is there any explicit rule indicates when a task added to global queue will be performed on main thread?

So time consuming tasks put in the global queue wouldn't affect the main thread.

like image 912
anb Avatar asked Jun 25 '26 17:06

anb


1 Answers

You said:

Technically, global queue finds an idle thread to run the task, which might be the main thread.

Generally global queue selects a thread of the appropriate quality of service from the pool of worker threads. When grabbing a worker thread, it is not the case that it might just randomly grab the main thread. It only selects from its pool of worker threads.

What you are seeing here is a very specific optimization for synchronous calls (but not asynchronous calls). As the sync docs say:

As a performance optimization, [sync] executes blocks on the current thread whenever possible, ...

This optimization is possible with synchronous calls because the current thread will be blocked during a synchronous dispatch, anyways. So GCD can avoid the costly context switch that is not needed/desired. It's a clever little optimization.

So, when will the aforementioned performance optimization not be employed? The above documentation quote continues:

... with one exception: Blocks submitted to the main dispatch queue always run on the main thread.

So, if you do the converse of your example (i.e., dispatch synchronously from a background queue to the main queue, or any queue that uses the main queue as its ultimate “target”), the optimization is turned off and it will do the context switch to the main thread, regardless. It has to do that because there are certain API calls and the like which must happen on the main thread, so the optimization is disabled in this scenario.

There are other, less well documented, scenarios where this optimization may not be employed. One would be well advised to not overly rely on this optimization. Just rest assured that when GCD can, it will attempt to avoid costly context switches for synchronously dispatched tasks.

like image 97
Rob Avatar answered Jun 28 '26 10:06

Rob



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!