【问题标题】:Nonblocking io_service::run非阻塞 io_service::run
【发布时间】:2018-09-01 08:33:53
【问题描述】:

我正在尝试实现一个包含两个处理循环的 C++ 应用程序。目前,第一个处理循环(boost 的 io_service::run)阻止了第二个处理循环的执行。

使用线程或 std::async 方法的方法失败。 (我没有多线程方面的经验/背景)。

是否有一种优雅的方式可以在另一个线程中运行 io_service::run,同时仍对传入的 UDP 数据报执行回调?

主文件:

class Foo
{
public:
    Foo();

    void callback(const int&);
private:
    // ... (hopefully) non-relevant stuff...
};

int main()
{

  Foo foo_obj;

  // I need to run this function (blocking) but the constructor is blocking (io_server::run())
  run();

  return 0;
}


Foo::Foo(){
    boost::asio::io_service io;

    UDP_Server UDP_Server(io);

    // Set function to be called on received message
    UDP_Server.add_handler(std::bind(&Foo::callback, this, std::placeholders::_1));

    // This function should be non-blocking
    // -> tried several things, like threads, async, ... (unfortunately not successful)
    io.run();
}

// realization of callback function here (see class definition)

包含自定义“库”:

class UDP_Server
{
public:
    UDP_Server(boost::asio::io_service&);

    void add_handler(std::function<void(int)>);

private:
    // Function handle
    std::function<void(int)> callbackFunctionHandle;

    // Functions
    void start_receive();
    void handle_receive(const boost::system::error_code&, std::size_t);

    // ... (hopefully) non-relevant stuff...
};

// Constructor
UDP_Server::UDP_Server(boost::asio::io_service& io_service)
    : socket_(io_service, udp::endpoint(udp::v4(), UDP_PORT)){

}

// Store a callback function (class foo) to be called whenever a message is received
void UDP_Server::add_handler(std::function<void(int)>  callbackFunction){
    try
    {
        callbackFunctionHandle = callbackFunction;
        start_receive();
    }
    catch (std::exception& e)
    {
        std::cerr << e.what() << std::endl;
    }
}

// Async receive
UDP_Server::start_receive()
{
  socket_.async_receive_from(
      boost::asio::buffer(recv_buffer_), remote_endpoint_,
      boost::bind(&UDP_Server::handle_receive, this,
        boost::asio::placeholders::error,
        boost::asio::placeholders::bytes_transferred));
}

// When message is received
void UDP_Server::handle_receive(const boost::system::error_code& error,
std::size_t bytes_transferred)
{
  if (!error || error == boost::asio::error::message_size)
  {

    // ... do smth. with the received data ...

    // Call specified function in Foo class
    callbackFunctionHandle(some_integer);

    start_receive();
}
else{
  // ... handle errors
}

}

【问题讨论】:

  • 是什么阻止您使用单个io_service
  • 我使用的是单个io_service另一个阻塞函数(由单个run()表示)是一个与ROS相关的ros::spin()
  • 感谢您的参考。我还看了run_one()。问题是我经常通过 UDP 接收消息,应该尽快处理。所以,我应该坚持run(),对吧?

标签: c++ multithreading asynchronous blocking nonblocking


【解决方案1】:

看看他们在here做了什么:

boost::asio::io_service io_service;
/** your code here **/
boost::thread(boost::bind(&boost::asio::io_service::run, &io_service));
ros::spin();

因此,您基本上在与 ros::spin() 不同的线程中启动对 io_service::run() 的阻塞调用。

如果你启动绑定到单个 cpu 节点(为了不浪费 2 个 cpu 节点等待命令)你的调度程序可能会处理一些事情。

【讨论】:

  • 我收到Bus error: 10 代码错误,我不知道为什么。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-06
  • 1970-01-01
  • 2013-03-12
  • 1970-01-01
  • 2012-11-13
相关资源
最近更新 更多