boost::python для приостановки и возобновления работы C++ через python
У меня есть простой класс C++, для которого я создал оболочку для взаимодействия с Python 2.7. Теперь я хотел бы иметь возможность вызывать метод этого класса ExampleClass::simulate(double sim_time) через python и приостанавливать метод / поток, вызывая другой метод ExampleClass::pause(). Очень упрощенный пример будет выглядеть примерно так:
#include<iostream>
#include<unistd.h>
class ExampleClass {
public:
void simulate(double sim_time)
{
pause_ = false;
int count = 0;
while (count < 10) {
std::cout << "simulating.\n";
sleep(1);
while(pause_) {
std::cout << "paused.\n";
sleep(1);
}
count += 1;
}
}
void pause()
{
pause_ = true;
}
void resume()
{
pause_ = false;
}
private:
bool pause_;
};
С соответствующей оболочкой Python:
void simulate_wrapper(ExampleClass* ec, double t_sim)
{
PyGILState_STATE gstate = PyGILState_Ensure();
ec->simulate(t_sim);
PyGILState_Release(gstate);
}
BOOST_PYTHON_MODULE(ExampleExt)
{
PyEval_InitThreads();
boost::python::class_<ExampleClass>("ExampleClass")
.def("pause",&ExampleClass::pause)
.def("resume",&ExampleClass::resume)
.def("simulate", &simulate_wrapper);
}
Тогда в Python у меня есть:
import threading
import time
import ExampleExt
ec = ExampleExt.ExampleClass()
t_sim = 2
def simulate(ec, t_sim):
print ('starting simulation.')
t = time.clock()
ec.simulate(t_sim)
dt = time.clock() - t
print ('simulation took',dt, 'seconds')
threading1 = threading.Thread(target=simulate, args=(ec,t_sim))
threading1.daemon = True
threading1.start()
Но когда я создаю объект ExampleClass в ipython и запускаю функцию имитации, я не могу запустить другие команды. Я читал о GIL, и, по-видимому, он блокирует все события ввода / вывода Python, поэтому я думаю, что это действительно не то, что я должен делать. Особенно потому, что я хочу изменить член pause_ во время работы метода имитации. Есть мысли о том, как заставить это работать?
Спасибо
Редактировать: я пробовал Boost:: Thread, чтобы посмотреть, решит ли это мою проблему, с некоторыми интересными результатами. Вот как я изменил свою обертку:
#include<example_class.hh>
#include<iostream>
#include<boost/python.hpp>
#include<boost/thread/thread.hpp>
#include<boost/bind.hpp>
void simulate_wrapper(ExampleClass* ec, double t_sim)
{
boost::thread t1(boost::bind(&ExampleClass::simulate,ec, t_sim));
}
И мой скрипт.py выглядит так:
import ExampleExt
ec = ExampleExt.ExampleClass()
t_sim = 2
ec.simulate(t_sim)
Все остальное так же, как и раньше. Теперь, когда я запускаю скрипт.py, я могу без проблем использовать методы паузы и возобновления, но когда метод имитации заканчивается, я получаю SIGSEGV. Что может быть причиной?
Спасибо за любые идеи!