-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Calling a Julia function from a non-Julia thread #17573
Comments
One way to do this is to have a Julia task waiting to receive requests from your thread. You can send requests from another thread by calling There was some discussion of this in the julia-users mailing list, and this mechanism is used in ZMQ.jl to some extent. |
See also #5657, which added this discussion of thread-safe callbacks to the manual. |
Note that as @yuyichao mentioned, this is a very long-term feature request – even when we have fully non-experimental Julia threading, calling Julia code from a non-Julia thread may still not work. Given that reality, the |
@stevengj Thanks, I had actually seen that in the docs, but I wonder if it would lead to a deadlock here? The QML application is started from Julia, blocking the main Julia process (i.e. the REPL is unresponsive). Would the request to render then not block until the QML app is closed? @StefanKarpinski I realise that now, thanks. I'm somewhat reassured by the Qt docs that the option for single-threaded rendering is also used in other circumstances and not likely to go away soon. |
If the Julia thread is "blocked" in the uv event loop, then it's not really blocked in the sense that C code is blocked – i.e. in the middle a call to the kernel and unable to do anything. So sending work to it via |
@barche, if the main thread is blocked in the Qt event loop, not the Julia event loop, then you indeed would have a deadlock problem. Combining two event loops is always problematic. Three options:
You can also find some other discussion online of merging libuv and Qt event loops, but I haven't seen anything very elegant. |
For me the
I am aware that the things I am allowed to do a very limited in the |
It can acquire pthread locks, the only restriction is that it can't interact with the julia runtime. |
OK, I've experimented with @stevengj Running the Qt event loop in another thread (using |
If it's waiting in the Qt event loop, use the qt equivalent of uv_async_send |
@yuyichao Just tried this, the deadlock remains, so it seems that is purely Qt related and I'll not clutter the discussion further with this. |
It seems that in practice a crash happens in // FIXME - need JL_ATOMIC_FETCH_AND_ADD here Would fixing that be a major part of the solution, or is that just the first of a long series of required steps? |
No. That change is undesired right now and is completely unrelated to this issue. |
@barche, if the GUI thread needs to be the main thread, why not start the Julia eventloop in another thread? |
@stevengj I haven't tried that because I couldn't figure out how to do that. Note that the entry point to the code is the julia executable, not a custom program that initialises the embedding interface. I think this fixes the Julia event loop on the main thread. |
@barche, you would have to make the entry point a custom executable that links |
@stevengj Yes, but it would disturb the workflow for QML.jl, where you can just launch the GUI from a normal Julia program now. Even with a custom main application, I would still need to make an async call into Julia for every callback from QML, and adding that seems like a lot of work. For now I prefer to await the improvements to the basic Julia threading infrastructure. The separate main application might be interesting when distributing a full-blown GUI application built on Julia, though, where users would expect to just click an icon rather than firing things up from the command line. |
Is there any work around which works currently? |
Aside from the |
Rephrasing my question: |
@ravismula, it is used in ZMQ.jl for thread-safe deallocation. |
Is there a plan on writing a simple example in the documentation that demonstrates data sending from a multi-threaded C-API while using the thread-safe |
Hi, I've tried to implement the async work sending to the main Julia thread from any C++ thread in https://github.com/cdsousa/embedding_julia/blob/master/julia_cpp_ts.cpp . It seems to work well but I have not used it anywhere besides that test. The work dispatch in the Julia thread side is a little hacky though. Nevertheless, it seems that the real solution to the original issue would be to enable the registration of external (to Julia) threads with Julia --- setting up TLS, registering with the GC and stacks, etc. It would be better that such new threads won't go to the worker thread pool though. Refs #16134. |
People, core devs, I've been peeking to the code, trying to get a big picture of the multithreading system, but it has been hard to get it. It would be marvelous to have some schematics on this but I understand that with such source code so much in flux (just like with recent partr addition) that is hard to maintain. I'm trying to realize what is the minimum to add threads during runtime (not available as a worker). Is there a place where one can understand the architecture of multithreading support, other than the code (and comments) itself? |
Is there any progress on this issue? On recent Julia Virtual meetup with @JeffBezanson and @StefanKarpinski it was the top-liked question. In our particular use-case we tried to use audio I/O C-library called libportaudio, which creates a separte thread for audio processing. It is impossible to pass julia algorithm there since it immediatly fails with segmentation fault. Using |
Is it possible to implement the |
Ok, fishing for help here. I've had limited success in the following strategy inspired by @vchuravy 's code in #17573 (comment)
And, um, after all this, was unreasonably excited when I was able to get it to kind of work. I feel like I'm close, but I still need a way for the "fake" callback to wait until the "real" callback is finished. Has anyone figured this out? @vtjnash 's comment
seems like a potential answer, if I could figure out what a pthread lock is and how to use it... |
I recently came up against two libraries where I needed a more principled approach and sat down today I haven't battle-tested the implementation, but in case others are interested. |
Wooo! |
Very nice, many thanks! |
As discussed on julia-users, I would like for it to be possible to call a Julia function from a non-Julia thread:
https://groups.google.com/forum/#!topic/julia-users/TqC79eYTYx8
My use case is calling a Julia OpenGL rendering function from within the QML rendering thread. The current workaround is to force Qt to use the non-threaded rendering engine.
The text was updated successfully, but these errors were encountered: