我有一个简单的 c++ 类,我已经构建了一个包装器,用于将它与 python 2.7 接口。现在,我希望能够通过 python 调用该类的方法 ExampleClass::simulate(double sim_time) 并通过调用另一个方法 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()
但是当我在 ipython 中创建一个 ExampleClass 对象并运行模拟函数时,我无法运行任何其他命令。我正在阅读有关 GIL 的内容,显然它会阻止所有 python I/O 事件,所以我想这真的不是我应该做的。特别是因为我想在模拟方法运行时修改成员 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 脚本时,我可以毫无问题地使用 pause 和 resume 方法,但是当模拟方法完成时,我得到一个 SIGSEGV。可能是什么原因造成的?
感谢您的任何见解!