Heyho everybody. [This Thread](https://forum.nim-lang.org/t/10719) sent me down somewhat of a rabbit hole that I'm still trying to climb out of about Multithreading within an application. Specifically, setting a GTK-application up with a server-client architecture in cases where you have a rather heavy program or other kinds of heavier computation that you don't want to block the GTK main thread.
There are mechanisms to push one-off tasks into separate threads, but for tasks that require the thread to stay alive the entire time and being pinged with commands occasionally that mechanism isn't suitable. #### system/channel So I did as suggested and implemented something like that for owlkettle using nim's system/channels (see my later posts in the prior thread or [this SO question](https://stackoverflow.com/questions/77591469/how-to-have-a-message-from-a-thread-channel-trigger-an-update-in-owlkettle) ). From what I understand, nim's system/channels take care of memory for you and deep-copy the message from Thread A to Thread B, thus guaranteeing memory safety. #### GAsyncQueue Chatting a bit on the GTK matrix server about it lead me down the rabbit hole of **their** thread-safe mechanism for inter-thread communication: [GAsyncQueue](https://docs.gtk.org/glib/struct.AsyncQueue.html). That one appears to work based on everything being a pointer and moving ownership of pointer1 from Thread A to Thread B. I haven't implemented this in nim yet, but that seems a bit more difficult to do as I'd need to convert a given ref-type into a pointer, disable destructors for said ref-data to avoid use-after-frees, only to cast them from pointers to "propper" types in Thread B and free them manually after the fact. #### threading/channel Chatting a bit more on our discord then lead me down the rabbit hole of system/channel's possible (drop-in ?) replacement: [threading/channel](https://github.com/nim-lang/threading). That one... actually seems like basically system/channel but while trying to do less copying when possible and more moving ownership around (?). The module warns about being experimental, which makes me slightly hesitant to propose adding it to a library that more than just a few others may depend on. #### Question Given that I am not that well versed in multi-threaded programming and in many respects this is my first time doing such a deep-dive into things: Does anyone have any thoughts on what might be the most sensible to use? Any aspects I am overlooking or where I have the wrong idea? With my current knowledge, this is my understanding: * Generally, GAsyncQueue has the benefit of zero-copying and a stable API. But the drawback of likely being a mild pain to properly implement to play nice with ARC/ORC. I'd imagine particularly ensuring messages don't get free'd on thread 1 and do get free'd on thread 2 would be meh. * The system/channel approach has the benefit that it currently exists and basically just works flawlessly. But the drawback that it does a lot of copying (which I don't really think has that much of an impact unless a ton of messaging is happening). * The threading/channel implementation has the benefit (I think?) of being a drop-in replacement for system/channel while simultaneously opening up the option to also transferring pointer ownership instead of deep-copying them. Which kinda seems like the best of both worlds, but with the drawback that it seems like a risky decision in this scenario. * I'm aware Malebolgia exists but my brain is mildly toast after today and I _think_ it doesn't focus on having mechanisms for inter-thread communication (?)