[英]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())時,會創建線程。 Thread包含一個函數“obj_engine”,它具有無限循環(while(true))。 在循環中有兩個函數:1。wait() - 使線程休眠5秒。 2. walk() - 簡單地說x + 1這兩個函數在結束后通過定義obj_action來相互切換。
現在我想將此更改為,當構造和對象,異步move()函數將被執行時,並且在move()函數之后,將執行異步wait()函數,反之亦然。 所以我不需要使用任何線程。
我希望得到這樣的結果:
//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();
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.