开发者

Timed function call

开发者 https://www.devze.com 2023-01-29 19:00 出处:网络
I am programming in C++, Linux environment. How could I call a function after a certain interval in asynchronous manner and also at regular interval? I found Boost timer at http://www.boost.org/doc/li

I am programming in C++, Linux environment. How could I call a function after a certain interval in asynchronous manner and also at regular interval? I found Boost timer at http://www.boost.org/doc/libs/1_40_0/doc/html/boost_asio/tutorial/tuttimer2.html. However, it needs to call io.run() to invoke the callback, which in turns bring me back to the original problem of needing me to take care of the elapsed time to call the function.开发者_运维问答 What I need is something like the C# System.Threading.Timer which would call back the function I passed after the time period specified.

I am thinking of creating a thread for each function call. However, I have quite a large number of such timer callback. Hence, I am afraid it would be expensive to create such threads or do I have other options?

Thanks.


The asio io_service runs in its own thread, once you schedule a timer event, it will call you back at the appropriate time.

Here is a complete example:

#include <iostream>
#include <boost/asio.hpp>
#include <boost/bind.hpp>

using namespace std;

class timed_class
{
public:
  timed_class(boost::asio::io_service& io_service) : _timer(io_service)
  {
    // now schedule the first timer.

    _timer.expires_from_now(boost::posix_time::milliseconds(100)); // runs every 100 ms
    _timer.async_wait(boost::bind(&timed_class::handle_timeout, this, boost::asio::placeholders::error));
  }

  void handle_timeout(boost::system::error_code const& cError)
  {
    if (cError.value() == boost::asio::error::operation_aborted)
      return;

    if (cError && cError.value() != boost::asio::error::operation_aborted)
      return; // throw an exception?

    cout << "timer expired" << endl;

    // Schedule the timer again...
    _timer.expires_from_now(boost::posix_time::milliseconds(100)); // runs every 100 ms
    _timer.async_wait(boost::bind(&timed_class::handle_timeout, this, boost::asio::placeholders::error));
  }

private:
  boost::asio::deadline_timer _timer;
};


int main(void)
{
  boost::asio::io_service io_service;

  timed_class t(io_service);

  io_service.run();

  return 0;
}

EDIT: to dispatch in a separate thread,

boost::thread t(boost::bind(&boost::asio::io_service::run, &io_service));

Instead of io_service.run();, now the main thread will continue and once the timeout has expired, then the io_service will call handle_timeout


Pseudocode for the simplest solution:

function doThis() {
    // your code here
}

function threadHandler() {
    sleep(SecondsUntilTime);
    doThis();
}

function main () {
    anotherthread = thread_create(threadHandler);

    // more code here

    join(anotherthread);
    exit();
}


One option is to switch to glib-- or Qt for their event loop, and write your code using that.

0

精彩评论

暂无评论...
验证码 换一张
取 消