官网教程:https://think-async.com/Asio/asio-1.26.0/doc/asio/tutorial/tuttimer3.html
如何将附加参数传递给处理程序函数。
#include <iostream>
#include <asio.hpp>
#include <boost/bind/bind.hpp>
要使用asio实现重复计时器,您需要在完成处理程序中更改计时器的到期时间,然后启动新的异步等待。显然,这意味着完成处理程序需要能够访问计时器对象。为此,我们为打印功能添加了两个新参数:
指向计时器对象的指针;和
一个计数器,这样我们就可以在计时器第六次启动时停止程序
在参数列表的末尾。
void print(const asio::error_code& /*e*/,
asio::steady_timer* t, int* count)
{
如上所述,本教程程序使用计数器在计时器第六次触发时停止运行。然而,您会注意到,没有明确的调用来要求io_context停止。回想一下,在Timer.2教程中,我们了解到io_context::run()函数在没有更多“工作”要做时完成。当计数达到5时,不在计时器上启动新的异步等待,io_context将耗尽工作并停止运行。
if (*count < 5)
{
std::cout << *count << std::endl;
++(*count);
接下来,我们将计时器的到期时间从上一个到期时间移动一秒钟。通过计算新的到期时间相对于旧的到期时间,我们可以确保计时器不会因为处理处理程序的任何延迟而偏离整个第二个标记。
t->expires_at(t->expiry() + asio::chrono::seconds(1));
然后我们在计时器上开始一个新的异步等待。正如您所看到的,boost::bind函数用于将额外的参数与完成处理程序相关联。steady_timer::async_wait()函数需要一个具有签名void(const asio::error_code&)的处理程序函数(或函数对象)。绑定附加参数会将打印函数转换为与签名正确匹配的函数对象。
有关如何使用Boost::Bind的更多信息,请参阅Boost.Bind文档。
在本例中,boost::bind的asio::placeholder::error参数是传递给处理程序的错误对象的命名占位符。启动异步操作时,如果使用boost::bind,则必须仅指定与处理程序的参数列表匹配的参数。在Timer.4教程中,您将看到,如果完成处理程序不需要参数,则可能会忽略此占位符。
t->async_wait(boost::bind(print,
asio::placeholders::error, t, count));
}
}
int main()
{
asio::io_context io;
添加了一个新的计数变量,这样我们就可以在计时器第六次启动时停止程序。
int count = 0;
asio::steady_timer t(io, asio::chrono::seconds(1));
与步骤4一样,当从main调用steady_timer::async_wait()时,我们绑定了print函数所需的额外参数。
t.async_wait(boost::bind(print,
asio::placeholders::error, &t, &count));
io.run();
最后,为了证明count变量正在打印处理程序函数中使用,我们将打印出它的新值。
std::cout << "Final count is " << count << std::endl;
return 0;
}
#include <iostream>
#include <asio.hpp>
#include <boost/bind/bind.hpp>
void print(const asio::error_code& /*e*/,
asio::steady_timer* t, int* count)
{
if (*count < 5)
{
std::cout << *count << std::endl;
++(*count);
t->expires_at(t->expiry() + asio::chrono::seconds(1));
t->async_wait(boost::bind(print,
asio::placeholders::error, t, count));
}
}
int main()
{
asio::io_context io;
int count = 0;
asio::steady_timer t(io, asio::chrono::seconds(1));
t.async_wait(boost::bind(print,
asio::placeholders::error, &t, &count));
io.run();
std::cout << "Final count is " << count << std::endl;
return 0;
}