首页 > 解决方案 > boost::python 线程通过 python 暂停和恢复 c++ 函数

问题描述

我有一个简单的 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。可能是什么原因造成的?

感谢您的任何见解!

标签: multithreadingpython-multithreadingboost-pythongilpausing-execution

解决方案


推荐阅读