Open KyleFromKitware opened 6 years ago
scoped_interpreter
holds a GIL by design, but gil_scoped_release
is meant to let you release it (i.e. when you know it is safe to do so). This, then, should work:
#include <pybind11/pybind11.h>
#include <pybind11/embed.h>
#include <iostream>
#include <thread>
static void thread()
{
pybind11::gil_scoped_acquire acquire;
std::cout << "Calling Python code from new thread" << std::endl;
}
int main()
{
pybind11::scoped_interpreter interp;
{
pybind11::gil_scoped_acquire acquire;
std::cout << "Calling Python code from main thread" << std::endl;
}
{
pybind11::gil_scoped_release release;
std::thread(thread).join();
}
return 0;
}
Just to check: Is this resolved by https://github.com/pybind/pybind11/pull/1211?
Let's say we have the following minimal example:
We would expect this to print:
But the
cout
from the new thread is never reached because of a GIL deadlock. The reason this is happening is becausePyEval_InitThreads()
, in addition to initializing threads, also acquires the GIL and never releases it.gil_scoped_acquire
callsPyEval_InitThreads()
the first time it runs, and it acquires the GIL a second time, so even whengil_scoped_acquire
is destructed, the GIL is still held.If we change the example to this:
then everything behaves as expected. Is this what I'm supposed to do, or is this a bug in pybind?