hi Daiwen: sync blocks the current thread while the task runs on mySerialQueue. So, in this example, the value statement doesnât run until changeValue() has finished.
In the async version, the value statement runs immediately, so shows the old value.
when you dispatch sync to a concurrent queue from two loops, the results can appear in a different order on each run, because the concurrent queue can run more than one task at a time, and you get a race condition
when you dispatch sync to a serial queue from the two loops, the results appear in alternate order each time, because the tasks run in exactly the same order they get added to the serial queue
the usleep(100) seems to favour the second loop: the runner1 result always appears first; if I comment out the sleeps, the runner0 result appears first.
Hi Audrey, great tutorial! Very clear and concise. I finished the whole course and reorganized my own knowledge and code ever used at work.
My other previous co-workers ever used DispatchSemaphore, is it old Objective-C thread safe tools, or part of GCD? Can I use serial queue to replace semaphore in the project? Thanks!
while the dispatch semaphore technique is a wonderful technique when absolutely needed, I must confess that I see too many new developers, unfamiliar with good asynchronous programming patterns, gravitate too quickly to semaphores as a general mechanism for making asynchronous routines behave synchronously.
And WWDC 2015 and 2016 GCD talks have pointed out that Appleâs priority inversion fix (promoting lower priority tasks) doesnât work with dispatch semaphores, because they donât have an owning task, so the system canât tell where theyâre being triggered.
Earlier in the WWDC 2015 talk, they discuss the use of serial queues as locks. Serial queues can take advantage of the priority inversion fix, so if thatâs a factor in your project, you should try to use a serial queue. OTOH if itâs not broken ⊠;]
One more question. In a project for the code not related to UI and I donât assign a global queue to execute it, will the system assign a global queue or main queue automatically? For example, in viewDidLoad(), I call a method to get data from a third-party API by using URLSession and I donât assign a global queue. Will the system execute it on a global queue or main queue? ( I understand after getting the data, in the completion handler I use main queue to update UI.)
a URLSession is an operation queue, so runs everything off the main queue â thatâs why you have to dispatch UI updates to the main queue when the task finishes or while the task is running.
you could watch my URLSession video course next ;]
Got it, thanks. I will watch your URLSession video course next.
So if the func in the previous question is not downloading data via URLSession, letâs say a func (called func A) to calculate some numbers and return an Int. If I execute this func A in viewDidLoad and donât assign a queue, the system will use a global queue or main queue?
If I want some task to run on a global queue, I must assign one global queue otherwise the system will run on main queue by default? (Except the scenario like URLSession, already runs off the main queue)
most things run on the main queue unless you dispatch them to another queue or add an operation to an operation queue
there are some APIs that run asynchronously, like URLSession and animations â when you look up examples or documentation, they usually advise you to run UI updates on the main queue.
In the URLSession course, I kept some UI code off the main queue, to demonstrate Xcode 9âs new main thread checker (edit scheme > Run > Diagnostics), which is very good at telling you which code must run on the main queue ;]
in video 2 where you describe the different cases of the qos enum, I dont understand the .userInteractive. You say everything that belongs to holding the UI responsive(like refreshing, updatingâŠ) shall be added to this concurrent queue. But I thought tasks updating the UI have to be performed on the main queue? Can you explain this in more detail?
hi tamaril: I took those descriptions from Appleâs Energy Efficiency Guide for iOS Apps, and itâs true their description of .userinteractive includes âoperating on the main thread, refreshing the user interfaceâ but the 3rd example is animations, which donât run on the main queue.
I think itâs because these quality of service levels are also used for Operations in OperationQueues, where the system takes over control of where to dispatch tasks. So specifying UserInteractive bumps up the priority to âdo immediatelyâ.
hi Mansi: serial/concurrent arenât equivalent to sync/async. You dispatch tasks from one queue to another queue. Serial/concurrent is about what happens on the destination queue: tasks run serially or concurrently.
Sync/async is about what happens on the source thread: the thread blocks or doesnât block while the task runs on the destination queue. If the source queue is serial, thereâs only one thread, so a serial queue blocks if you dispatch synchronously from it.
Another great tutorial ! Iâll admit the Introduction Video was a bit long for an introduction but part 2 is good. I wish the web page video player had a back 10 seconds button on it. I find myself fumbling about as I rewind the video to catch a missed point.
At 20:25 your comment about dispatching a block of code synchronously to main serial queue from the main thread as a deadlock seems like an easy mistake to make. Good tip
Your quick example running a sync block of code on concurrent queue probably should be prefaced that it makes little sense to do this. Is that not correct ? All it does is run the code block from the calling thread when the queued message is finally extracted.
The example showing how to make a variable access synchronized is nice to know. It looks like the Swift team could have made a convenience wrapper word âsynchronizedâ in the variable declaration as a less verbose way of doing this.
It doesnât matter whether you run a task Synchronously or Asynchronously on a concurrent queue? Because it will just create a new thread for the new task anyway?
Also, it doesnât matter whether you run a task Synchronously or Asynchronously on a serial queue either? Because it has to wait for the task to complete before starting a new one?