[C++-sig] X-language polymorphism and multithreading

Anton Yabchinskiy arn at bestmx.ru
Sat Jul 3 03:03:53 CEST 2010


On 2010-07-02 18:27:39-0500, Charles Solar wrote:
> Threads and python do not mix very well.  You need to handle locking and
> unlocking the gil at the boundaries of python and c++.
> There are several posts here about this problem, just search for thread or
> 'no current thread' in the archives.
> A month ago I posted a modified boost python that will handle the gil
> correctly for you if you want to give that a shot, or there is also TnFox
> which also handles threads correctly.
> 
> Basically the short answer to your question is that you most certainly can,
> but you need to understand how the gil works and when and where you need to
> have it in order to do it correctly.

So, I need PyGILState_Ensure/PyGILState_Release around the
overridden method call, and PyEval_InitThreads in the module
initialization. Am I right? Is the following code OK?

#include <boost/python.hpp>
#include <boost/python/suite/indexing/vector_indexing_suite.hpp>

#include "../xyzzy.hpp"

using namespace boost::python;
using namespace xyzzy;

namespace {

class GIL_State_Guard
{
public:
    GIL_State_Guard() :
        state_(PyGILState_Ensure())
    {
    }

    ~GIL_State_Guard()
    {
        PyGILState_Release(state_);
    }

private:
    PyGILState_STATE state_;
};

class Data_Listener_Wrapper : public Data_Listener, public wrapper<Data_Listener>
{
public:
    void
    on_data(const Data_Buffer& data)
    {
        if (override on_data = get_override("on_data")) {
            GIL_State_Guard guard;

            on_data(data);
        }
        default_on_data(data);
    }

    void
    default_on_data(const Data_Buffer& data)
    {
        Data_Listener::on_data(data);
    }
};

}// namespace

BOOST_PYTHON_MODULE(xyzzy) {

    PyEval_InitThreads();

    class_<Data_Buffer>("Data_Buffer")
        .def(vector_indexing_suite<Data_Buffer>());

    class_<Data_Listener_Wrapper, boost::noncopyable>("Data_Listener")
        .def("on_data", &Data_Listener::on_data, &Data_Listener_Wrapper::default_on_data);

    class_<Data_Provider, boost::noncopyable>("Data_Provider")
        .def("start", &Data_Provider::start)
        .def("stop", &Data_Provider::stop);

}


More information about the Cplusplus-sig mailing list