Multithreaded GUI application

I have read that people gave up on multi threaded GUIs as it was to complicated to handle the locks and stuff. That is why we ended up with a GUI thread and worker threads for long lasting operations. That is also why sometimes GUIs freeze because some action took longer as exspected and the programmer didn't move it into a worker thread.

With rusts fearless multithreading and ownership build in. Would it be possible to write a multi threaded GUI framework in rust?

So maybe it starts with a thread that does the initialization and then the frameworks creates new threads for each event. So each button clicked,.. would be a separate thread. This way a freeze-up would not be possible. Worker threads would not be needed. There would probably be a performance hit due to creating all the threads, but that is probably not an issue on most machines today. And can maybe be mitigated by using thread pools?

Or do I miss something here and it not possible. Then what am I missing? What are the reasons that this will not work?

Rust can stop you from making many types of mistakes in your multi-threaded code, but it doesn't change the fact that multi-threaded code is usually more complicated than single-threaded code. We are already having a hard time writing a single-threaded GUI application in Rust.

There are some pieces that can be offloaded of course. E.g. when you want to start a long running operation, send it off to another thread. You can do this in Rust of course, but it's worth mentioning that people have already figured out how to do that in other languages

I spent most of 2020 writing a heavily multi-threaded UI application in Rust, and the main problem is that even though you won't have problems with soundness, Rust does not protect you from deadlocks at all, and those are very time-consuming to track down.

My solution was to move to a message-based architecture (using the bastion crate), but besides the issue that many developers in the team could just not switch their mindset to the way you have to do stuff there (it's absolutely not possible to call certain functions synchronously, because they're part of a different concurrent task and the data they need isn't Sync), it also caused issues with third party crates and especially C/C++ libraries that expected their stuff to run on a single thread (I've had to file multiple tickets about implementing Send in various crate repositories).

It also resulted in user interactions giving delayed feedback, because some queue was filled up and needed to be processed in order before the user input was handled and the change slowly propagated back to the display. I ended up having to fake applying changes on the UI side, so they could be applied to the backend as well at a later date.

In the end, all of the overhead of synchronization took up more real-world time than the processing itself and resulted in a worse user experience overall.

4 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.