From 7cfe8b0595914f12978cc81a002e0adc81dff043 Mon Sep 17 00:00:00 2001 From: Martijn Visser Date: Mon, 7 Jul 2025 09:45:57 +0200 Subject: [PATCH 1/2] Add FAQ on interactive threads Documents https://github.com/JuliaPy/PythonCall.jl/issues/586. --- docs/src/faq.md | 7 ++++++- docs/src/pythoncall.md | 2 ++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/docs/src/faq.md b/docs/src/faq.md index d78bf486..764ef911 100644 --- a/docs/src/faq.md +++ b/docs/src/faq.md @@ -10,7 +10,7 @@ To force PythonCall to use the same Python interpreter as PyCall, set the enviro Alternatively, to force PyCall to use the same interpreter as PythonCall, set the environment variable `PYTHON` to [`PythonCall.python_executable_path()`](@ref) and then `Pkg.build("PyCall")`. You will need to do this each time you change project, because PythonCall by default uses a different Python for each project. -## Is PythonCall/JuliaCall thread safe? +## [Is PythonCall/JuliaCall thread safe?](@id faq-multi-threading) Yes, as of v0.9.22, provided you handle the GIL correctly. See the guides for [PythonCall](@ref jl-multi-threading) and [JuliaCall](@ref py-multi-threading). @@ -18,6 +18,11 @@ Yes, as of v0.9.22, provided you handle the GIL correctly. See the guides for Before, tricks such as disabling the garbage collector were required. See the [old docs](https://juliapy.github.io/PythonCall.jl/v0.9.21/faq/#Is-PythonCall/JuliaCall-thread-safe?). +When starting a Julia REPL with multiple threads, there must be exactly one interactive thread, +to avoid triggering a segmentation fault on tab completion. +Check this with `Threads.nthreads(:interactive)` or `versioninfo()`, set it with `JULIA_NUM_THREADS=X,1`, +where `X` is the number of default threads, or use the Julia `--threads` CLI flag, see `julia --help`. + Related issues: [#201](https://github.com/JuliaPy/PythonCall.jl/issues/201), [#202](https://github.com/JuliaPy/PythonCall.jl/issues/202), diff --git a/docs/src/pythoncall.md b/docs/src/pythoncall.md index 8b8f19a1..4f67269a 100644 --- a/docs/src/pythoncall.md +++ b/docs/src/pythoncall.md @@ -392,6 +392,8 @@ Both `@unlock` and `@lock` are important. If the GIL were not unlocked, then a d would occur when attempting to lock the already-locked GIL from the threads. If the GIL were not re-locked, then Python would crash when interacting with it. +With multiple Julia threads you need exactly one interactive thread, see the [FAQ](@ref faq-multi-threading). + You can also use [multi-threading from Python](@ref py-multi-threading). ### Caveat: Garbage collection From d3353223afcbdad8136c56c9fa4d0b694e4d1468 Mon Sep 17 00:00:00 2001 From: Martijn Visser Date: Wed, 9 Jul 2025 20:50:16 +0200 Subject: [PATCH 2/2] Add link to the issue --- docs/src/faq.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/faq.md b/docs/src/faq.md index 764ef911..76e268fe 100644 --- a/docs/src/faq.md +++ b/docs/src/faq.md @@ -19,7 +19,7 @@ Before, tricks such as disabling the garbage collector were required. See the [old docs](https://juliapy.github.io/PythonCall.jl/v0.9.21/faq/#Is-PythonCall/JuliaCall-thread-safe?). When starting a Julia REPL with multiple threads, there must be exactly one interactive thread, -to avoid triggering a segmentation fault on tab completion. +to avoid triggering a segmentation fault on tab completion (issue [#586](https://github.com/JuliaPy/PythonCall.jl/issues/586)). Check this with `Threads.nthreads(:interactive)` or `versioninfo()`, set it with `JULIA_NUM_THREADS=X,1`, where `X` is the number of default threads, or use the Julia `--threads` CLI flag, see `julia --help`.