BOOST如何在线程中发送信号并在另一个线程中执行相应的槽?

Gui*_*e07 11 c++ boost signals

例如,如果你在GUI线程之外的线程中发出信号,信号被排队并在GUI线程中稍后执行,那么有没有办法用boost来做到这一点?

谢谢

chi*_*ila 18

对于事件循环,请使用boost :: asio :: io_service.您可以在线程安全的方式中在此对象中发布任务并让另一个线程执行它们:

struct MyClass
{
    boost::io_service service;
    void doSomethingOp() const { ... }

    void doSomething()
    {
        service.post(boost::bind(&MyClass::doSomethingOp, this));
    }

    void loop()
    {
            service.run(); // processes the tasks
    }
};

boost::signal<void()> mySignal;

MyClass myClass;
mySignal.connect(boost::bind(&MyClass::doSomething, boost::ref(myClass)));

// launches a thread and executes myClass.loop() there
boost::thread t(boost::bind(&MyClass::loop(), boost::ref(myClass)));

// calls myClass.doSomething() in this thread, but loop() executes it in the other
mySignal(); 
Run Code Online (Sandbox Code Playgroud)

  • THX这个非常有用的样本!由于不推荐使用boost :: signal,我必须使用boost :: signals2 :: signal <>. (3认同)

小智 5

这是上述io_service, ,executor_work_guard的完整示例signals2::signal

  • io_service是事件循环处理程序
  • executor_work_guard确保m_service.run()不仅仅执行一次
  • signal/slot解耦发送者和接收者
  • 运行thread所有进程io_service
#include <boost/thread.hpp>
#include <boost/asio/io_service.hpp>
#include <boost/asio/executor_work_guard.hpp>
#include <boost/signals2/signal.hpp>

class IOService
{
public:
  IOService() : m_worker(boost::asio::make_work_guard(m_service)) {}
  ~IOService() {}

  // slot to receive signal
  void slotMessage(std::string msg)
  {
    m_service.post(boost::bind(&IOService::process, this, msg));
  }

  // start/close background thread
  bool start()
  {
    if (m_started)
      return true;
    m_started = true;

    // start reader thread
    m_thread = boost::thread(boost::bind(&IOService::loop, this));
    return m_started;
  }

  void loop()
  {
    m_service.run();
  }

  void close()
  {
    m_worker.reset();
    if (m_thread.joinable())
      m_thread.join();
    m_started = false;
  }

  // process
  void process(std::string msg)
  {
    printf("process %s\n", msg.c_str());
  }

private:
  bool m_started = false;
  boost::asio::io_service m_service;
  boost::asio::executor_work_guard<boost::asio::io_context::executor_type> m_worker;
  boost::thread m_thread;
};

int main()
{
  // service instance
  IOService serv;
  serv.start();

  // signal to slot
  boost::signals2::signal<void(std::string)> signalMessage;
  signalMessage.connect(boost::bind(&IOService::slotMessage, boost::ref(serv), _1));

  // send one signal
  signalMessage("abc");

  // wait and quit
  boost::this_thread::sleep(boost::chrono::seconds(2));
  serv.close();
}
Run Code Online (Sandbox Code Playgroud)