Kotlin Native. Multithreading with Coroutines

The main idea of Kotlin Multiplatform, as well as other cross-platform SDKs, is to optimize development by writing code once and share it between different platforms. However, there are some nuances that should be figured out and solved according to the platform specifics. One such moment is the concurrency. KMM SDK uses the specific for every native platform version of Kotlin: Kotlin/JVM, Kotlin/JS, or Kotlin/Native. Kotlin Native is really different from Kotlin JVM because it depends on the specifics of the iOS platform. Most default solutions that work with JVM are not suitable for Kotlin Native at all. In this story we will discuss about the basic approach to deal with concurrency for iOS and Kotlin Native in Kotlin Multiplatform.

Kotlin Multiplatform provides common way to implement the multithreading. It uses Kotlin, so we can use Coroutines for all our targets:

Next we need to setup scopes and contexts of coroutines to work with main and background threads:

Because of platform specific code we need to use expect/actual mechanism to setup correct versions for every platform we use.
For both Android and iOS we can use Default and Main dispatchers:

There are no problem with concurrency in JVM and Android, so we will focus just on Kotlin Native. And there we will face some nuances.
If we use provided by default dispatchers and share some objects between main and background threads, we can get FreezingException:

In Kotlin Native we can share between threads only immutable objects. And to make an object or block of code immutable, we should use freeze() command. To incapsulate and hide all the work with freezing under the hood, we can create our own Coroutine Dispatchers:

It is absolutely correct to use MainDispatcher to work with main queue. But dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT.toLong(), 0.toULong()) cannot be used for Global queue, because in Kotlin Native it is not bound to any particular thread.
We can use MainDispatcher for both main and background thread:

ThreadLocal annotation is used to make a singleton object shareable between threads.

Using MainDispatcher looks really strange. But it is ok, when we use it with such library as Ktor (for e.g). Because Ktor already has an asynchronous mechanism implemented under its hood.

But what if we don’t want to use Ktor? How can we deal with background threads in this case?
We can try to use Global Scope. But it is not recommended, because of potential leaks and lack of control under all coroutines launched in this scope:

We can use simple workaround to manage all our coroutines in Global scope. But it still be not safe.

We can run our custom made dispatcher in other scope:

And it will work.
Also we can use special native-mt versions of coroutine library that allow us to use multithreaded coroutines, such as 1.5.2-native-mt. Because the main version of kotlinx.coroutines is a single-threaded one, libraries will almost certainly rely on this version. We can face InvalidMutabilityException in this case. Another problem is memory leaks while using multithreaded coroutines.

Well, it seems to be really tricky to use Coroutines in Kotlin Native. How to deal with concurrency without Coroutines, we will discuss on the next story.




Experts on various Google products talking tech.

Recommended from Medium

What in REST, How in GraphQL

Enable continuous deployment for multi-container app to Swarm cluster in Azure using VSTS

Successfully porting complex data-driven frontends to React with GraphQL

The Future of Software Industry-A look into the current trends

A Complete Go Development Environment With Docker and VS Code

Principles of Pair Agile Coaching

Creating your AI projects on Kaggle

Accelerate Machine Learning with the Optimal Deployment Pattern

Photo showing a small yacht and a large ship entering the Miraflores Locks, Panama Canal

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Anna Zharkova

Anna Zharkova

My name is Anna Zharkova, I'm from Barnaul. Lead Mobile developer, more than 7 years of experience. I develop both native and cross platform. Kotlin GDE

More from Medium

Going Modular — The Kotlin Multiplatform Way

Android Gradle plugin with Test Fixtures support

Out with Retrofit and in with KTor Client