29 Ocak 2018 Pazartesi

asio deadline_timer Sınıfı

Giriş
Boost içindeki en eski timer sınıfıdır. Posix sistem saatini kullanır. basic_deadline_timer sınıfından kalıtır.

Daha yeni sınıflar ise basic_waitable_timer sınıfından kalıtırlar. Yeni sınıflar hem boost::chrono hem de std::chrono ile beraber kullanılabilir. Dolayısıyla bence C++11 kullanan kodlarda deadline_timer artık kullanılmamalı.

Posix sistem saati için şu satır dahil edilir.
#include <boost/date_time/posix_time/posix_time.hpp>
Yanlış Kullanım
Bu timer local_time ile kurulmamalıdır.
Örnek
Şu kullanım şekli yanlıştır.
boost::posix_time::ptime time =  boost::posix_time::microsec_clock::local_time();
timer.expires_at(time + boost::posix_time::time_duration(0,0,10));
Örnek
Şu kullanım şekli de yanlıştır.
ptime time (boost::gregorian::day_clock::local_day()), hours(15)+minutes(12));
timer.expires_at(time);
Her zaman şöyle kullanılmalıdır.
boost::posix_time::microsec_clock::universal_time()
Ayrıca NTP saat güncellemelerinden etkilenir. Elle yapılan saat düzeltmelerinden etkilenir.

Constructor
Şöyle yaparız
boost::asio::deadline_timer t (io_service);
Sınıf içinde tanımlıyorsak şöyle yaparız.
class A {
public:
  A();
private:
  boost::asio::io_service io;
  boost::asio::deadline_timer t;
};
Sınıfın constructor'ında şöyle yaparız.
A::A() : t(io) {
    // do stuff
}
Şu kod yanlıştır ve derlenmez. Derleyici t (io) kodunu member initialization yerine metod çağrısı olarak algılar.
A::A() {
    t(io);
    // do stuff
}
Hata olarak şunu alırız.
error: no match for call to ‘(boost::asio::deadline_timer {aka boost::asio::basic_deadline_timer}) (boost::asio::io_service&)
Constructor - expiration time
Absolute veya relative time alan bir constructor daha var. expires_at() veya expires_from_now() metodunu çağırmaya gerek kalmaz.Şöyle yaparız.
boost::asio::deadline_timer t (ios, boost::posix_time::seconds(3));
Şöyle yaparız.
boost::posix_time::ptime p = boost::posix_time::time_from_string("...");
boost::asio::deadline_timer t (ios, p);
async_wait metodu - coroutine
Şöyle yaparız.
#include <boost/asio.hpp>
#include <boost/asio/spawn.hpp>

int main()
{
  boost::asio::io_service io_service;
  boost::asio::deadline_timer timer(io_service);
  timer.expires_from_now(boost::posix_time::pos_infin);

  boost::asio::spawn(io_service,
    [&](boost::asio::yield_context yield)
    {
      // As only one thread is processing the io_service, the posted
      // timer cancel will only be invoked once the coroutine yields.
      io_service.post([&](){ timer.cancel(); });

      // Initiate an asynchronous operation, suspending the current coroutine,
      // and allowing the io_service to process other work (i.e. cancel the 
      // timer).  When the timer is cancelled, the asynchronous operation is
      // completed with an error,  causing the coroutine to resume.  As an
      // error_code is provided, the operation will not throw on failure.
      boost::system::error_code ec;
      timer.async_wait(yield[ec]);
      assert(ec == boost::asio::error::operation_aborted);
    });

  io_service.run();
}
async_wait metodu - handler
Şöyle yaparız.
t.async_wait (std::bind(&foo::ondeadline, this,std::placeholders::_1));
handler şöyledir.
void foo::ondeadline (const boost::system::error_code& ec) {  
  if (!err)
    ...
  }    
}
async_wait metodu - handler + timer
Şöyle yaparız.
void handler(const error_code& ec, boost::shared_ptr<asio::deadline_timer> t)
{
}

t.async_wait(
  boost::bind(&handler, boost::asio::placeholders::error, t));
cancel metodu
Açıklaması şöyle. Eğer time kuyruğa girmiş ise cancel edilemez. Handler çağrıldığı zaman bir hata kodu ile cancel edildiğini anlayabiliriz.
If the timer has already expired when cancel() is called, then the handlers for asynchronous wait operations will:
  • have already been invoked; or
  • have been queued for invocation in the near future.
These handlers can no longer be cancelled, and therefore are passed an error code that indicates the successful completion of the wait operation.
Şöyle yaparız.
t.cancel();
cancel_one metodu
Şöyle yaparız.
t.cancel_one();
expires_at metodu
Şöyle yaparız.
t.expires_at(microsec_clock::universal_time() + milliseconds(500));
expires_from_now metodu
Şöyle yaparız.
t.expires_from_now (boost::posix_time::seconds(2));
wait metodu
Açıklaması şöyle.
This function is used to wait for the timer to expire. This function blocks and does not return until the timer has expired.
Örnek
Şöyle yaparız.
io_service ios;
io_service::work work(ios);
thread thread([&] { ios.run() });

service.post([&]
{
   deadline_timer timer(ios, posix_time::seconds(100000);
   timer.wait();
});

service.post([&]
{
   std::cout << "HELLO!";
}):

thread.join();
Diğer
event Gibi Kullanımı
timer içeren bir sınıf tanımlarız.
class event
{
public:
  explicit
  event(boost::asio::io_service& io_service) 
    : timer_(io_service)
  {
    // Setting expiration to infinity will cause handlers to
    // wait on the timer until cancelled.
    timer_.expires_at(boost::posix_time::pos_infin);
  }

  template <typename WaitHandler>
  void async_wait(WaitHandler handler)
  {
    // bind is used to adapt the user provided handler to the deadline 
    // timer's wait handler type requirement.
    timer_.async_wait(boost::bind(handler));
  }

  void notify_one() { timer_.cancel_one(); }
  void notify_all() { timer_.cancel();     }

private:
  boost::asio::deadline_timer timer_;
};
Şöyle yaparız
void on_event() { std::cout << "on_event" << std::endl; }

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

  // Add work to service.
  event.async_wait(&on_event);

  // Run io_service.
  boost::thread thread(boost::bind(&boost::asio::io_service::run,
                       &io_service));

  // Trigger event, causing the on_event handler to run.
  event.notify_one();

  thread.join();  
}



Hiç yorum yok:

Yorum Gönder