从boost::threads到boost::asio定时器
From boost::threads to boost::asio timers
在我的项目中,每个类对象都有自己的线程,内部有无限循环(while(1)),其中执行特定的对象函数。我正试图改变这一点,以便每个对象都能与计时器异步执行其功能。
基本上,这就是它与线程和无限循环的工作方式:
class obj
{
public:
obj();
~obj();
//custom functions and variables
int x;
int obj_action;
move();
wait();
}
obj()
{
obj_action=1;
//when constructing object, make its thread with infinite while cycle
boost::thread make_thread(boost::bind(&obj::obj_engine,this));
}
void obj::obj_engine()
{
while(true)
{
if (obj_action==1){move();}
else if (obj_action==2){wait();}
Sleep(1);
}
}
void obj::move()
{
x++;
obj_action==2;
}
void obj::wait()
{
Sleep(5000);
obj_action==1;
}
这个例子展示了obj类,它有构造函数、析构函数、变量对和函数对。当构造一个对象(obj())时,就会产生线程。线程包含一个函数"obj_engine",该函数具有无限循环(while(true))。循环中有两个函数:1.wait()-使线程睡眠5秒。2.walk()-简单地x+1这两个函数在结束后通过定义objaction相互切换。
现在我想把它改为,当构造和对象时,将执行异步move()函数,在执行move(。所以我不需要使用任何线程。
我希望这样的结果:
//constructing
obj()
{
asynchronous(walk());
}
walk()
{
x++
asynchronous(wait());
}
wait()
{
Sleep(5000);
asynchronous(walk());
}
我听说你可以用boost::asio定时器做到这一点,但我真的不知道怎么做。如果有人能教我怎么做,我将不胜感激。
开始:
#include <boost/asio.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/bind.hpp>
#include <iostream>
class obj {
public:
obj() : x_(0), t_(io_service_, boost::posix_time::seconds(5)) {
t_.async_wait(boost::bind(&obj::move, this));
io_service_.run();
}
void move() {
x_++;
std::cout << x_ << std::endl;
t_.expires_at(t_.expires_at() + boost::posix_time::seconds(5));
t_.async_wait(boost::bind(&obj::move, this));
}
private:
int x_;
boost::asio::io_service io_service_;
boost::asio::deadline_timer t_;
};
int main(int, char**) {
obj a;
while(true);
}
基本上,asio教程涵盖了您所需要的一切:本教程向您展示了如何使用异步计时器,本教程向你展示了如何重置计时器。
更新:
请使用上面的源代码,而不是我最初的源代码-由于io_service_.run()
的重复调用,每个move
调用都会在另一个线程中调用,一段时间后你的应用程序会因此崩溃。上面的代码修复了这个问题,并通过这样做去掉了wait
函数。
借用nijansen的例子,我已经拼凑出了一些应该与您想要的更相似的东西(我认为)。
这里的关键是io_service应该在所有对象的调度之间共享。通常每个线程有一个io_service,但也可以使用更复杂的方案。只要io_service上安排了工作(挂起超时或等待套接字),io_service::run
就会运行。当没有安排更多的工作时,它只是返回。
您可能对io_service::post
感兴趣,它是在"活动对象"之间发送消息的一种方式(即使它们在不同的io_services和不同的线程下运行,它也能工作)。您可能希望查看boost::bind
,也可能查看boost::signals
。
#include <boost/asio.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/bind.hpp>
#include <iostream>
namespace asio = boost::asio;
class obj {
public:
obj(asio::io_service& ioSvc)
: x_(0), t_(ioSvc)
{
schedule_in(5);
}
void schedule_in(int seconds) {
t_.expires_from_now(boost::posix_time::seconds(3));
t_.async_wait(boost::bind(&obj::move, this));
}
void move() {
x_++;
std::cout << x_ << std::endl;
schedule_in(5);
}
private:
int x_;
boost::asio::deadline_timer t_;
};
int main(int, char**) {
boost::asio::io_service io_service;
obj a(io_service);
obj b(io_service);
obj c(io_service);
io_service.run();
}
- Ardunio UNO解决了多个重叠的定时器循环
- 我们能否在stm32f中使用硬件定时器控制两个独立的进程
- Arduino Nano:A4988 使用串行输入时通过定时器进行步进控制不稳定
- 没有信号处理程序的POSIX定时器的目的是什么?
- 在定时器回调函数中使用 Sleep() 会导致C++出现问题吗?
- 如何在Qt中修改QWebsocket定时器
- C++Windows中的高分辨率定时器库
- 如何用单个信号处理程序解决这个多linux定时器的问题
- C#/.NET定时器和Win32睡眠函数都是不精确的
- Udp 在 QT 定时器信号中写入数据报
- AVR CTC模式下的16位定时器
- Linux C++定时器与软实时支持
- 在Qt中实现精确定时器
- 在不中断串行的情况下禁用Arduino上的定时器0中断
- 跨平台C++高精度事件定时器实现
- 从boost::threads到boost::asio定时器
- boost::asio::steady_timer的大定时器偏移量
- 在c++中唤醒boost::sleep定时器并将其重置为0
- 使用boost::asio定时器进行线程安全工作
- Qt应用程序中的Boost定时器