非阻塞 io_service::run
Posted
技术标签:
【中文标题】非阻塞 io_service::run【英文标题】:Nonblocking 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()
boost.org/doc/libs/1_42_0/doc/html/boost_asio/reference/…
感谢您的参考。我还看了run_one()
。问题是我经常通过 UDP 接收消息,应该尽快处理。所以,我应该坚持run()
,对吧?
【参考方案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
代码错误,我不知道为什么。以上是关于非阻塞 io_service::run的主要内容,如果未能解决你的问题,请参考以下文章