How to add thread support to the application(GTK -rs)

Hi,

I need to run in another thread very long task, because when I do it in main thread, then UI freeze until this tasks ends.

Now when user press button, then everything is done at once in function at once.

I want when user press search button create a new thread which will execute very long functions, and when it ends, prints results to GUI.

But GTK support drawing only in one thread, so I can’t simply create UI from another thread because it will crash application.

So how I can handle it?
Should I check in each frame if thread ends?

You can’t send gtk or modify them from other threads directly. Usually you can offload the work you need to do to a different thread by decoupling it from the widgets and then sending the result over to the main thread through a channel. If what you want to do is populate a listmodel or treestore, instead of doing it using other threads you could split the work and do it asynchronously.

This blogpost is a good resource but will need to be adapted for rust.

https://www.bassi.io/pages/lazy-loading/

To add to what @alatiera said, for channels, you can either use futures channels (the GLib mainloop is a futures executor) or the glib::MainContext::channel(). For the latter, see this for some examples/background.

1 Like

I added support for support for executing commands in other thread(https://github.com/qarmin/czkawka/commit/be30afdac6a200058f32723a37b554ef776b44ed) and it seems to work fine, but I don’t know how I could kill created process when needed.

(Stop button in GIF should immediately killl other thread and allow user to search again or change tabs but I don’t know how to implement this.)

You would have to share something (at least a bool) between your main thread and the background thread so that the background thread can periodically check if it should continue its tasks or should cancel it.

Another option instead of explicitly using a background thread would be to make use of the glib::ThreadPool. Its push_future() function allows to push new tasks to the pool and retrieving the results via a Future.

I used crossbeam_chanell to add support for multi producer, multi consumer chanell(https://docs.rs/crossbeam-channel/0.4.4/crossbeam_channel/).
I just create a new thread and put to it cloned receiver, and after processing every single file I check if something come to chanell, if yes I set dirty flag.
At the end I send with glib::MainContext::channel() command to check and draw results

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.