JuliaGraphics / QML.jl

Build Qt6 QML interfaces for Julia programs.
Other
387 stars 35 forks source link

Threading #24

Open jtravs opened 8 years ago

jtravs commented 8 years ago

Not really an issue, but a question: is there a way to use multiple threads with QML.jl? Either Julia threads or Qt ones? It is for the usual problems; i.e. computational process in background with responsive GUI in foreground.

barche commented 8 years ago

Unfortunately, not at this moment, see https://github.com/JuliaLang/julia/issues/17573 The usual workaround can be applied using event loops, however. In QML.jl you can use exec_async() instead of exec() to launch the application, and then the REPL will remain responsive. An example is in example/repl-background.jl, after including this from the repl you can type e.g. plot(rand(4,4)) to see a plot in the QML window (requires Plots.jl and PyPlot.jl)

ihnorton commented 7 years ago

@barche on the JuliaLang issue you mentioned:

at the same time have the rendering thread wait for the callback to complete.

If you set a uv_cond_t condition variable in your render thread before calling the async send, it should be possible to safely uv_cond_wait on it, and then signal from the callback to release.

barche commented 7 years ago

I think I tried that, but got a deadlock. I spent hours trying different synchronization schemes, but none worked. My final attempt ended in this unanswered question: https://forum.qt.io/topic/70649/qquickframebufferobject-render-function-on-main-thread

Note that even with the asynchronous stuff all that happens is essentially forcing different threads to run in series, so effort would be much better spent resolving the Julia thread-safety issues.

jtravs commented 7 years ago

Is it possible to use the multi processing as a work around do you think (I might try this tonight). Basically I would change my non GUI worker thread to be a worker process instead.

ihnorton commented 7 years ago

Note that even with the asynchronous stuff all that happens is essentially forcing different threads to run in series, so effort would be much better spent resolving the Julia thread-safety issues.

Agreed on thread safety, but this case also involves external entry IIUC, which I don't think JVM has solved entirely even after X billion dollars of person-hours. Also, I think you will always have to thread-join for the duration of the gl context manipulation to use the qquickframebuffer, even in C++.

I'm curious how Qt have solved synchronization issues with QML/JavaScript interaction. Studying that might be informative.

@jtravs

Is it possible to use the multi processing as a work around do you think (I might try this tonight). Basically I would change my non GUI worker thread to be a worker process instead.

With shared data arrays? Maybe, but interprocess mutexes are harder to use than in-process ones, and can be much slower with some primitives on some platforms (ahem, Windows...). You will still be limited to a single GUI+render thread for whichever process is interacting with the Qt loop.

barche commented 7 years ago

@jtravs Could you maybe elaborate on the use case a little? Is theexec_async workaround insufficient for your problem?

jtravs commented 7 years ago

It might be sufficient, to be honest I haven't tried porting my code over to see. Here is what I'm wanting to do: I have a GUI that controls some lab equipment. Behind it I have three threads, two continuously grabbing data in parallel from some instruments (a camera, a spectrometer, not important) and a third running some analysis on that data. This data comes fast and needs to be processed in real time, the processing takes at least one core by itself. In the foreground the GUI needs to display this data in real time, and also allow me to start/stop/change parameters. Currently I'm using python with PyQt, but threading performance is not sufficient. I'm contemplating moving to C++. But I would love to use Julia and QML.jl if I am half convinced it would work. I think the limit in python is that they are not true threads and might try using multiprocessing in python as a workaround, but then I realized I could try Julia's equivalent.

barche commented 7 years ago

It should be possible to launch the QML gui from the main Julia process using async_exec, and then from the same process launch the working processes. You could then collect the data for the GUI in the main process. With async_exec the Julia event loop is in charge, so you can update the GUI periodically using e.g. context properties or plotting to a JuliaDisplay.

I have never used the multiprocessing on Julia, so I have no idea how convenient it is.

ufechner7 commented 1 year ago

Perhaps this can be closed now that 0.8 is released?

barche commented 1 year ago

Threading is still a work in progress actually. Some support for this is there with Julia 1.9, but multi-threaded programs hang with GC enabled.