Message pool: DispatchQueue.main.async

I worked in Java and was pretty clear about how threads and thread pool work.

I was wondering if someone could explain how thread creation and space allocation in the thread pool in swift works?

Besides,

Dispatch.main.async {
 // some code
}

      

Is it creating a new topic or is it running a task asynchronously?

Thanks in advance =)

+3


source to share


2 answers


Queues and threads are separate concepts. Queues are ordered (sometimes prioritized) by the sequence of blocks to be executed. As a (mostly) implementation detail, blocks need to be scheduled on threads for execution, but that's not their main point.

So it Dispatch.main.async

sends (adds) a block to the main queue. The main queue is serial and somewhat special as it must also be run exclusively on the main thread (as Paulw11 points out). It also promises to be linked to the main runloop. Understanding this "adds a block to a queue" concept is critical because it has a significant impact on how you create things in queues and how you design things in threads. async

doesn't mean "run this now". It means "stick with it in line, but don't wait for it."

As a good example of how projects can be different, putting something in the queue doesn't mean it will ever work (even without bugs or dead ends). It may be useful to suspend queues so they stop scheduling locks. It is possible to associate queues with other queues, so that when a queue "schedules" something, it simply puts it on another queue rather than executing it. There are many things you can do with queues that are not "running things in the background". You can attach completion handlers to blocks. You can use groups to wait for block collections. GCD is the way to think about concurrency. Parallelism is just a side benefit. (A great discussion of this Concurrency concept is not Parallelism by Rob Pike... It's in Go, but the concepts still apply.)

If you call Dispatch.main.async

while running on the main queue, then this block is absolutely certain that it will not execute until the current block has completed. In UIKit and AppKit, "the current block ends" often means "you are returning from a method that is called by the OS". Although not implemented, you can pretend that every time you call from the OS, it ends up with a call Dispatch.main.async

.



This is why you should never call Dispatch.main.sync

(check sync

) from the main queue. This block will wait for you to come back and you will wait until the block ends. Classic dead end.

Typically, thread pool is not your business on iOS. This is an implementation detail. Sometimes you have to think about it for performance reasons, but if you think about it too much, you are probably designing your concurrency wrong.

If you are going with Java, you definitely want to read "Migrating from Threads" in the concurrency programming guide. This is the ultimate resource for how to rethink thread-to-queue based patterns.

+7


source


Your code enqueues a block of code in the main queue ( Dispatch.main

) and returns immediately ( .async

) before executing the code.

You have no control over which thread is used in the queue. Even if you create your own queue:

let serialQueue = DispatchQueue(label: "queuename")
serialQueue.async { 
    ...
} 

      

you don't know which thread your code will run in.




Update:

As correctly pointed out by Paulw11 in the comment,

... if you send a task to the main queue, it will be executed on the main thread. If you submit the job to any other queue, you don't know which thread it will execute; it can run on the main thread or another thread.

+3


source







All Articles