简体   繁体   English

从boost :: threads到boost :: asio定时器

[英]From boost::threads to boost::asio timers

In my project every class object has its own thread with infinite cycle (while(1)) inside, in which particular object functions are performed. 在我的项目中,每个类对象都有自己的线程,内部有无限循环(while(1)),其中执行特定的对象函数。 And I'm trying to change this so that every object would perform its functions asynchronously with timers. 而我正试图改变这一点,以便每个对象都能与定时器异步执行其功能。

Basically this is how it works with thread with infinite loop: 基本上这是它与无限循环的线程一起工作的方式:

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;
}

This example shows, the obj class, which has constructor , destructor, couple of variables and couple of functions. 这个例子显示了obj类,它有构造函数,析构函数,几个变量和几个函数。 When constructing an object (obj()), thread is made. 构造对象(obj())时,会创建线程。 Thread contains a function "obj_engine" , which has infinite loop (while(true)). Thread包含一个函数“obj_engine”,它具有无限循环(while(true))。 In the loop there is two functions: 1. wait() - makes a thread sleep for 5 seconds. 在循环中有两个函数:1。wait() - 使线程休眠5秒。 2. walk() - simply x+1 those 2 functions switches each other after its end by defining obj_action. 2. walk() - 简单地说x + 1这两个函数在结束后通过定义obj_action来相互切换。

Now I want to change this to, when the constructing and object , asynchronously move() function would be performed, and after move() function, asynchronously wait() function would be performed, and vice verse. 现在我想将此更改为,当构造和对象,异步move()函数将被执行时,并且在move()函数之后,将执行异步wait()函数,反之亦然。 So I wouldn't need to use any threads. 所以我不需要使用任何线程。

I hoping for result like this: 我希望得到这样的结果:

//constructing
obj()
{
       asynchronous(walk());
}

walk()
{
    x++
    asynchronous(wait());
}

wait()
{
    Sleep(5000);
    asynchronous(walk());
}

I heard you can do this, with boost::asio timers , but I really don't know how. 我听说你可以用boost :: asio计时器做到这一点,但我真的不知道怎么做。 I would be very grateful if someone would show me how. 如果有人能告诉我如何,我将非常感激。

Here you go: 干得好:

#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);
}

Basically everything you need is covered by the asio tutorial: this tutorial shows you how to use an asynchronous timer , and this tutorial shows you how to reset your timer . 基本上你需要的东西都包含在asio教程中: 本教程向你展示了如何使用异步计时器本教程将向你展示如何重置你的计时器

Update: 更新:

Please use the above source code instead of my initial one - due to the repetitive calls of io_service_.run() , each move call would be called in another thread and after some time your application would crash because of it. 请使用上面的源代码而不是我的初始代码 - 由于io_service_.run()的重复调用,每个move调用都将在另一个线程中调用,并且一段时间之后您的应用程序将因此而崩溃。 The above code fixes this problem, and gets rid of the wait function by doing so. 上面的代码解决了这个问题,并通过这样做摆脱了wait函数。

Borrowing the example from nijansen, I've whipped together something that should be more similar to what you want (I think). 借用nijansen的例子,我把一些应该更符合你想要的东西(我想)。

The key here is the io_service should be shared between all object's scheduling on it. 这里的关键是io_service应该在所有对象的调度之间共享。 Usually there is one io_service per thread, but more intricate schemes can be used as well. 通常每个线程有一个io_service,但也可以使用更复杂的方案。 io_service::run runs for as long as there is work scheduled on the io_service (pending timeout or waiting on a socket). 只要io_service上有工作计划(挂起超时或等待套接字), io_service::run运行。 When no more work is scheduled, it simply returns. 当不再安排工作时,它只会返回。

You might be interested in io_service::post as a way to send messages between your "active objects" (which works even if they are running under different io_services and different threads). 您可能对io_service::post感兴趣,作为在“活动对象”之间发送消息的方式(即使它们在不同的io_services和不同的线程下运行,它也能工作)。 You may want to look at boost::bind and possibly boost::signals . 你可能想看看boost::bindboost::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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM