# Is it possible to force a task to have a particular thread id?

**URL:** https://discourse.julialang.org/t/is-it-possible-to-force-a-task-to-have-a-particular-thread-id/129172
**Category:** General Usage
**Tags:** multithreading, concurrency, gui, qml
**Created:** [May 20, 2025, 10:50am UTC](https://discourse.julialang.org/t/is-it-possible-to-force-a-task-to-have-a-particular-thread-id/129172 "2025-05-20T10:50:35Z")
**Posts on this page:** 5
**Page:** 1

<div class="post-metadata">

### Author: ![AwesomeQuest](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/awesomequest/32/38910_2.png) [@AwesomeQuest](https://discourse.julialang.org/u/AwesomeQuest)
#### Post date: [May 20, 2025, 10:50am UTC](https://discourse.julialang.org/t/is-it-possible-to-force-a-task-to-have-a-particular-thread-id/129172/1 "2025-05-20T10:50:35Z")

</div>

I’m trying to make a GUI in QML.jl that does a lot of things asynchronously. In order to improve performance I would like to run Julia with multiple threads since everything is organized into tasks anyway.  
But QML.jl doesn’t like multi-threading, randomly giving an undefined reference error (though this is better than what I got with Tk.jl which just crashed Julia).

So since all communications with QML need to be single threaded I was thinking one solution would be to designate a particular thread to do the communicating, but there doesn’t seem to be any particular support for this.

What’s the best way to do this? Can I force particular tasks to run on a particular thread or should I just use a zero/single buffer `Channel` for force sequential operations?

---

<div class="post-metadata">

### Author: ![nilshg](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nilshg/32/2283_2.png) [@nilshg](https://discourse.julialang.org/u/nilshg)
#### Post date: [May 20, 2025, 12:18pm UTC](https://discourse.julialang.org/t/is-it-possible-to-force-a-task-to-have-a-particular-thread-id/129172/2 "2025-05-20T12:18:00Z")

</div>

Have you read this recent discussion and the links therein?

> [@Why has simple threading using \`threadid\` become so complex in v1.12...?](https://discourse.julialang.org/t/why-has-simple-threading-using-threadid-become-so-complex-in-v1-12/129135/6):
>
> The documentation for both OhMyThreads.jl and ChunkSplitters.jl do a great job at explaining how “simple” multithreading can work. As an example, [using ChunkSplitters.jl](https://juliafolds2.github.io/ChunkSplitters.jl/stable/multithreading/#@threads-and-enumerate), you could do: # setup n = Threads.nthreads() ds = mutable\_datastructure() dss = [deepcopy(ds) for \_ in 1:n] outputs = zeros(length(some\_iterable)) Threads.@threads for (i, c) in enumerate(chunks(some\_iterable; n=n)) local ds = dss[i] for j in c outputs[j] = computation!(ds, j) end end

I’ve not looked into this deeply, but the general gist I get from these conversations is that you shouldn’t rely on the thread id for anything.

---

<div class="post-metadata">

### Author: ![JamesNZ](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jamesnz/32/35361_2.png) [@JamesNZ](https://discourse.julialang.org/u/JamesNZ)
#### Post date: [May 20, 2025, 9:21pm UTC](https://discourse.julialang.org/t/is-it-possible-to-force-a-task-to-have-a-particular-thread-id/129172/3 "2025-05-20T21:21:21Z")

</div>

What you’re asking for is called task pinning, you can do it with the `@spawnat` macro from StableTasks.jl. I would recommend using a `Channel` for all the GUI updates and keep one pinned task reading from that `Channel` and processing the updates. The advantage of doing it with a single task instead of multiple tasks short-lived tasks is that you can easily implement something like logging to check the order in which updates are happening, which can be very useful when debugging.

---

<div class="post-metadata">

### Author: ![AwesomeQuest](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/awesomequest/32/38910_2.png) [@AwesomeQuest](https://discourse.julialang.org/u/AwesomeQuest)
#### Post date: [May 21, 2025, 2:25pm UTC](https://discourse.julialang.org/t/is-it-possible-to-force-a-task-to-have-a-particular-thread-id/129172/4 "2025-05-21T14:25:08Z")

</div>

Thanks a lot!  
Though I’m wondering about the `Channel`, is the reason I should make a channel consumer thread because that’s how Julia advises one to use threads or are there other reasons? I’m also a bit reluctant to do that because I’m trying to make the code accessible to non-experts and that would get complicated quick I think.

Also I notice that `@spawnat` takes a `threadid` as input, doesn’t that tie into the discussion mentioned above about `threadid` being bad?

---

<div class="post-metadata">

### Author: ![JamesNZ](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jamesnz/32/35361_2.png) [@JamesNZ](https://discourse.julialang.org/u/JamesNZ)
#### Post date: [May 21, 2025, 3:08pm UTC](https://discourse.julialang.org/t/is-it-possible-to-force-a-task-to-have-a-particular-thread-id/129172/5 "2025-05-21T15:08:37Z")

</div>

Ah sorry, I think I misread your message and requirements slightly. If you only want one task touching Qt at once then you don’t even need to worry about task pinning and sticky tasks, you can just launch a regular task as usual with `Threads.@spawn` (note that the naming is unfortunate, it creates a _task_ rather than OS thread). I mentioned task pinning because doing GUI things on threads other than thread 1 doesn’t really work on macOS but Qt has its own event loop that I assume will take care of thread-safety. Relying on `threadid` is indeed not the best practice but in some cases it’s unavoidable.

About using a `Channel`, it’s not necessary and mostly a matter of preference 🙂 You can also use a lock and ensure that the lock is acquired while communicating with Qt.
