Notlin native and threads

I’ve been experimenting with Kotlin native and multithreading. I’m working on a pretty low level, directly calling pthread_create and other low-level primitives.

I have noted that Kotlin native really doesn’t like me to access datastructures from new threads unless they have been frozen.

Is there a technical reason for this? I have some pretty low-level code where I want to use regular locks and shared datastructures, but there seems to be no simple way to achieve this.

I’m well aware of the arguments against shared datastructures and in favour of immutable shared data. For the most part I agree with them, but sometimes the best solution is to use traditional locks, and my question is how to achieve this in Kotlin native. And if it isn’t possible, I’d like to know the reasons for it. I’m wondering if it has something to do with how the garbage collector works?

Hi there,

Kotlin Native does not allow such programming practices for safety and ease of garbage collecting purposes. Take a look at the introduction in the documentation. Basically you won’t be using pthread and will instead rely on Worker and any value that is shared should be either immutable or detached/reattached in the correct thread.

1 Like

Thank you. I have read the documentation and understand it. I wanted to to know if this was merely a style issue, or whether there are actual technical reasons to prevent it. The documentation says the following:

Kotlin/Native runtime doesn’t encourage a classical thread-oriented concurrency model with mutually exclusive code blocks and conditional variables, as this model is known to be error-prone and unreliable.

The wording suggested to me that it’s recommended against because of style, not because it’s technically problematic. However, I do see some things that suggest that the runtime makes certain assumptions with regards to the mutability of shared objects. This makes be believe that perhaps the garbage collector requires it.

I was looking for the technical reasons as to why it it’s not allowed.

Oh sorry I misunderstood.

Well i guess you technically could use low level primitives, if you freeze everything. I don’t know if the detach/attach technique would work with anything other than workers though. As for why shared mutable values are not working, my guess is that it is because K/N tries to do automatic memory management without the use of a fully fledged GC like Java does.

GCs in concurrent context are very hard to get right (Java has been trying for god knows how many years and has gotten decent result only recently), K/N uses reference counting, which is the easiest of all, though not the most performant, or the most reliable in concurrent context.

This coupled with the fact that shared mutable values are considered bad practice (because they are hard to get right) pushed the decision to make K/N very restrictive regarding how you share your values.

Bottom-line is, you can try to share values and circumvent the K/N runtime, but I don’t know how stable it will be, if it is possible at all. Your best chance would be to manage your memory manually, like in C so K/N reference counter leaves you alone, but I don’t think it is the right thing to do.