首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >非阻塞io_service::run

非阻塞io_service::run
EN

Stack Overflow用户
提问于 2018-03-23 03:04:50
回答 1查看 603关注 0票数 2

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

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

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

Main-文件:

代码语言:javascript
复制
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)

包含自定义的“库”:

代码语言:javascript
复制
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
}

}
EN

回答 1

Stack Overflow用户

发布于 2020-03-13 00:09:32

看看他们在here中做了什么

代码语言:javascript
复制
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节点等待命令),您的调度程序可能会处理一些东西。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49436554

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档