What is Multithreading? Complete Guide.

Essential thread vs. background thread. Async/await and Actor. GCD vs. OperationQueue. Group dispatch, the best way to empower background thread, and extra

Multiple threads through a needle
Photograph by on

On this article, we are going to study the next:

Serial Queue vs. Concurrent Queue

Essential Thread (UI Thread) vs. Background Thread (World Thread)

I do know there are many matters. If one thing is already acquainted to you, skip it and skim the unknown elements. There are tips and ideas.

Think about you’ve got a restaurant. The waiter is gathering the orders. The kitchen is getting ready the meals, the bartender is making the espresso and the cocktails.

In some unspecified time in the future, a lot of individuals will order espresso and meals. That wants extra time to get ready. Immediately the bell rings that 5x meals is prepared and 4x coffees. The waiter might want to serve the tables one after the other even when all of the merchandise are ready. That is the Serial Queue. With a serial queue, you might be restricted to just one waiter.

Now think about there are two or three waiters. They’ll serve the tables a lot sooner on the identical time. That is Parallelism. Utilizing a number of CPUs for working a number of processes.

Now think about one waiter won’t serve one desk directly, however will first serve all of the coffees to all tables. Then, they are going to ask for the orders for a few of the new tables, then serve all of the meals. This idea is named Concurrency. It’s context switching, managing, and working many computations on the identical time. It doesn’t essentially imply they’ll ever each be working on the identical on the spot. For instance, multitasking on a single-core machine.

At present’s units all have a number of CPUs (). To have the ability to create apps with seamless flows, we have to perceive the idea of Multithreading. It’s a means how we are going to deal with some duties within the utility. It is very important perceive that if one thing “works,” perhaps it isn’t the very best, desired means. Numerous occasions I see a long-running activity that’s taking place on the UI thread and blocking the execution of the appliance for a few seconds. These days it could possibly be the no-go second. Customers might delete your utility as they really feel that different apps begin up sooner, make sooner fetch of the books, music. Competitors is large, and excessive requirements are anticipated.

Thread execution sorts

You’ll be able to see the “Serial 6″ activity whether it is scheduled on the present time. It will likely be added to the checklist within the FIFO method and ready to be executed sooner or later.

One factor I’ve struggled with is that there is no such thing as a normal terminology. To assist with that for these topics I’ll first write down the synonyms, examples. If you happen to come from another know-how than iOS, you can nonetheless perceive the idea and switch it because the fundamentals are the identical. I had luck that early in my profession I used to be working with C, C++, C#, node.js, Java(Android), and so on. so I acquired used to this context switching.

  • Essential thread / UI Thread: That is the thread that’s began with the appliance, pre-defined serial thread. It listens for person interplay and UI adjustments. All of the adjustments instantly want a response. Have to care to not add an enormous job to this thread because the app can freeze.
Lengthy-running activity on UI Thread (mistaken and shouldn’t do that)
// Run async code on the Essential/UI Thread. E.g.: Refresh TableView
  • Background Thread (international): Predefined. Principally we create duties on new threads primarily based on our wants. For instance, if we have to obtain some picture that’s large. That is performed on the background thread. Or any API name. We don’t need to block customers from ready for this activity to be completed. We are going to name an API name to fetch an inventory of films knowledge on the background thread. When it arrives and parsing is completed then we change and replace the UI on the primary thread.
Lengthy-running activity (performed the proper means on Background Thread)
DispatchQueue.international(qos: .background).async 
// Run async on the Background Thread. E.g.: Some API calls.
Instance of SerialQueue

Within the image above, we added a breakpoint to line 56. When it’s hit and the appliance stops, we are able to see this on the panel on the left facet of the threads.

  1. You’ll be able to see the identify of the DispatchQueue(label: “com.kraken.serial”). The label is the identifier.
  2. These buttons will be helpful to show off / filter out the system technique calls to see simply user-initiated ones.
  3. You’ll be able to see that we have now added sleep(1). This stops the execution of the code for 1 second.
  4. And if you happen to watch the order it’s nonetheless triggered in a serial method.

Primarily based on the earlier iOS, one of many two most used phrases are the Serial Queue and Concurrent Queue.

Instance of ConcurrentQueue
  1. That is consequence one in all Concurrent Queue. You’ll be able to see above the Serial / Essential Thread additionally (com.apple.main-thread).
  2. The sleep(2) is added up to now.
  3. You see there is no such thing as a order. It was completed async on the background thread.
let mainQueue = DispatchQueue.important
let globalQueue = DispatchQueue.international()
let serialQueue = DispatchQueue(label: “com.kraken.serial”)
let concurQueue = DispatchQueue(label: “com.kraken.concurrent”, attributes: .concurrent)

We are able to additionally create a non-public queue that could possibly be serial and concurrent additionally.

GCD is Apple’s low-level threading interface for supporting concurrent code execution on multicore {hardware}. In a easy method, GCD allows your telephone to obtain a video within the background whereas protecting the person interface responsive.

“DispatchQueue is an object that manages the execution of duties serially or concurrently in your app’s important thread or on a background thread.” — Apple Developer

If you happen to seen within the code instance above, you may see “qos.” This implies High quality of Service. With this parameter, we are able to outline the precedence as follows:

  • background — we are able to use this when a activity shouldn’t be time-sensitive or when the person can do another interplay whereas that is taking place. Like pre-fetching some pictures, loading, or processing some knowledge on this background. This work takes vital time, seconds, minutes, and hours.
  • utility — long-running activity. Some course of what the person can see. For instance, downloading some maps with indicators. When a activity takes a few seconds and finally a few minutes.
  • userInitiated — when the person begins some activity from UI and waits for the consequence to proceed interacting with the app. This activity takes a few seconds or an on the spot.
  • userInteractive — when a person wants some activity to be completed instantly to have the ability to proceed to the subsequent interplay with the app. Immediate activity.

It’s helpful can also be to label the DispatchQueue. This might assist us to establish the thread once we want it.

Usually we have to begin a number of async processes, however we want only one occasion when all are completed. This may be achieved by DispatchGroup.

“A gaggle of duties that you simply monitor as a single unit.”— Apple Docs

For instance, typically it’s worthwhile to make a number of API calls on the background thread. Earlier than the app is prepared for person interplay or to replace the UI on the primary thread. Right here’s some code:

Multithreading with DispatchGroup
  • Step 1. Create DispatchGroup
  • Step 2. Then for that group must name group.enter() occasion for each activity began
  • Step 3. For each group.enter() must be known as additionally the group.go away() when the duty is completed.
  • Step 4. When all of the enter-leave pairs are completed then group.notify is named. If you happen to discover it’s performed on the background thread. You’ll be able to configure per your want.
Dispatch Group. Process one by every person by notify.

It’s value mentioning the wait(timeout:) choice. It’ll wait a while for the duty to complete however after timeout, it is going to proceed.

“An object that controls entry to a useful resource throughout a number of execution contexts by use of a conventional counting semaphore.” — Apple Docs

Multithreading with DispatchSemaphore

Name wait() each time accessing some shared useful resource.

Name sign() once we are able to launch the shared useful resource.

The worth in DispatchSemaphore signifies the variety of concurrent duties.

A standard perception is that when a GCD activity is scheduled it may’t be cancelled. However this isn’t true. It was true earlier than iOS8.

“The work you need to carry out, encapsulated in a means that allows you to connect a completion deal with or execution dependencies.” — Apple Docs

For instance, in case you are utilizing a search bar. Each letter typing calls an API name to ask from the server-side for an inventory of films. So, think about in case you are typing “Batman.” “B,” “Ba,” “Bat”… each letter will set off a community name. We don’t need this. We are able to merely cancel the earlier name if, for instance, one other letter is typed inside that one-second vary. If time passes the one second and the person doesn’t kind a brand new letter, then we contemplate that API name must be executed.

SearchBar. Simulation “Debounce” with DispatchWorkItem

In fact, utilizing Practical Programming like RxSwift / Mix we have now higher choices like debounce(for:scheduler:choices:).

Dispatch Boundaries is resolving the issue with a learn/write lock. This makes certain that solely this DispatchWorkItem can be executed.

“This makes thread-unsafe objects thread-safe.” — Apple Docs

Dispatch Barrier
Barrier Timeline

For instance, if we need to save the sport, we need to write to some opened shared file, useful resource.

We are able to use this code to delay some activity execution:

Evil AsyncAfter. Unhealthy facet of Multithreading

From my perspective, that is the supply of all evil, with respect for exceptions. For each async activity that wants a delay, I’d counsel considering by this, and whether it is potential use some state administration system. Don’t choose this selection as the primary selection. Often, there’s one other means.

If you’re utilizing NSOperation meaning you might be utilizing GCD beneath the floor, as NSOperation is constructed on high of GCD. Some NSOperation advantages are that it has a extra user-friendly interface for Dependencies(executes a activity in a selected order), it’s Observable (KVO to watch properties), has Pause, Cancel, Resume, and Management (you may specify the variety of duties in a queue).

OperationQueue Instance. Choice 2 for iOS Multithreading

You’ll be able to set the concurrent operation rely to 1 so it is going to work as a serial queue.

queue.maxConcurrentOperationCount = 1
Serial OperationQueue
Concurrent OperationQueue
Group Concurrent OperationQueue

This final is the Dispatch Group. The one distinction is that it’s a lot simpler to jot down advanced duties.

DispatchSource is used for detecting adjustments in information and folders. It has many variations relying on our wants. I’ll simply present one instance beneath:

Instance the best way to monitor some “bodily” file

There’s a state of affairs when two duties can anticipate one another to complete. That is known as Impasse. The duty won’t ever be executed and can block the app.

Impasse in iOS Multithreading

By no means name sync duties on the primary queue; it is going to trigger impasse.

There’s a option to get a warning that we did one thing mistaken. This can be a actually helpful choice, and I like to recommend utilizing it. It could actually simply catch some undesirable points.

If you happen to open on the goal and edit the scheme as on the subsequent picture, activate the Essential Thread Checker, then once we do some UI replace on background, this selection on runtime will notify us. See the picture beneath for the purple notification:

Essential Thread Checker
Essential Thread Checker consequence
Technique identify the place is the difficulty will be seen

It’s also possible to see within the Xcode terminal what’s mistaken. For newcomers, it’s perhaps a little bit of a wierd message, however quick you’ll get used to it. However you may join that inside that line there’s the identify of the tactic the place the difficulty is.

Whereas debugging, there are a few tips that may assist us.

If you happen to add a breakpoint and cease at some line. Within the Xcode terminal you may kind the command thread information. It’ll print out some particulars of the present thread.

Debug the Threads in Code Terminal

Listed here are some extra helpful instructions for the terminal:

po Thread.isMainThread

po Thread.isMultiThreaded()

po Thread.present

po Thread.important

Perhaps you had an identical state of affairs — when the app crashed and within the error log you can see one thing like com.alamofire.error.serialization.response. This implies the framework created some customized thread and that is the identifier.

With iOS13 and Swift 5.5, the long-awaited Async / Await was launched. It was good of Apple that they acknowledged the difficulty that when one thing new is launched then a protracted delay is going on until it may be used on manufacturing as we normally must assist extra iOS variations.

Async / Await is a option to run asynchronous code with out completion handlers.

Easiest Async / Await

Right here is a few code value mentioning:

  • Process.isCancelled
  • Process.init(precedence: .background)
  • Process.indifferent(precedence: .userInitiated)
  • Process.cancel()

I’d spotlight TaskGroup. That is the “DispatchGroup” within the Await / Async world. I’ve discovered that Paul Hudson has a very nice instance on this .

Good Instance of TaskGroup by Paul Hudson

Actors are lessons, reference sorts which can be thread-safe. They deal with knowledge race and concurrency points. As you may see beneath, accessing the property of the actor is completed with await key phrase.

“Actors enable just one activity to entry their mutable state at a time.” — Apple Docs

Instance from

We’ve lined a lot of multithreading matters — from UI and Background Thread to Deadlocks and DispatchGroup. However I’m certain you are actually in your option to being an knowledgeable or at the least ready for iOS interview questions on multithreading matters.

The entire code pattern will be discovered on the subsequent hyperlink: . I hope will probably be helpful to play with it your self.

More Posts