I'm writing a python program that includes a c++ module (.so
, using boost.python
).
I'm starting several python threads that run a c++ function.
This is how the C++ code looks like:
#include <boost/python.hpp>
using namespace boost;
void f(){
// long calculation
// call python function
// long calculation
}
BOOST_PYTHON_MODULE(test)
{
python::def("f", &f);
}
And the python code:
from test import f
t1 = threading.Thread(target=f)
t1.setDaemon(True)
t1.start()
print "Still running!"
I encounter a problem: the "Still running!" message isn't shown, and I found out that the c++ thread is holding the GIL.
What is the best method of handling the GIL in my case of running c++ code from python code?
Thanks! Gal
I often find that using RAII-style classes to manage the Global Interpreter Lock (GIL) provides an elegant exception-safe solution.
For example, with the following
with_gil
class, when awith_gil
object is created, the calling thread acquires the GIL. When thewith_gil
object is destructed, it restores the GIL state.And the complementary
without_gil
class does the opposite:Their usage within a function could be as follows:
One can also use a higher level convenient class to provide a
std::lock_guard
like experience. The GIL acquisition and release, save and restore semantics are slightly different than a normal mutex. Hence, thegil_guard
interface is different:gil_guard.acquire()
will acquire the GILgil_guard.release()
will release the GILgil_guard_restore()
will restore the previous stateAnd its usage would be:
Here is a complete example demonstrating GIL management with these auxiliary classes:
Interactive usage: