boost :: python для приостановки и возобновления работы c ++ через python - PullRequest
0 голосов
/ 17 сентября 2018

У меня есть простой класс 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.Что может быть причиной?

Спасибо за любые идеи!

...