Boost logo

Boost Users :

Subject: Re: [Boost-users] playing around with tutorial codes to understand ioservice
From: Zachary Turner (divisortheory_at_[hidden])
Date: 2009-07-11 17:33:55


It might help to think of a single io_service *instance* as a single
event loop. When you invoke run() on instance X of an io_service from
thread Y, then X is allowed to post notifications to thread Y when an
event happens on that io_service. So, for example, if you have one
io_service and you invoke run() from 5 threads on the same instance,
then the all 5 threads will be participating in the event loop for
this instance of io_service. It is undefined which thread will
receive notification of an event, only that exactly 1 of the threads
in the event loop will wake up when something happens.

So if you have 2 io_service instances, then the output can be
interleaved if you call run from multiple threads.

In your program, you declare 2 io_services, but you actually only use
one. Maybe this is a typo? io2 isn't even used, so io2.run() just
returns instantly. I also rewrote your code a little. It helps to
print out the time until expiration for each timer.

boost::asio::io_service io,io2;
boost::asio::deadline_timer* timer1;
boost::asio::deadline_timer* timer2;

void print(const boost::system::error_code& /*e*/,
                   boost::asio::deadline_timer* t, int* count)
{
        if (*count < 5)
        {
                ++(*count);

                t->expires_at(t->expires_at() + boost::posix_time::seconds(1));

                std::cout << *count << ": " << ((t==timer1)?"timer1":"timer2") << ",
t1exp: " << timer1->expires_from_now() << ", t2exp: " <<
timer2->expires_from_now() << std::endl;

                t->async_wait(boost::bind(print,
                        boost::asio::placeholders::error, t, count));
  }
}

int main()
{
        int count = 0;
        timer1 = new boost::asio::deadline_timer(io, boost::posix_time::seconds(1));
        timer2 = new boost::asio::deadline_timer(io, boost::posix_time::seconds(1));

        std::cout << "[start]: t1exp: " << timer1->expires_from_now() << ",
t2exp: " << timer2->expires_from_now() << std::endl;

        timer1->async_wait(boost::bind(print,
boost::asio::placeholders::error, timer1, &count));
        timer1->expires_at(timer1->expires_at() + boost::posix_time::seconds(1));

        timer2->async_wait(boost::bind(print,
boost::asio::placeholders::error, timer2, &count));

  io.run();
  io2.run();

  std::cout << "Final count is " << count << "\n";

  int discard;
  std::cin>>discard;
  return 0;
}

[start]: t1exp: 00:00:01, t2exp: 00:00:01
1: timer1, t1exp: 00:00:03, t2exp: 00:00:01
2: timer2, t1exp: 00:00:02, t2exp: 00:00:01
3: timer2, t1exp: 00:00:01, t2exp: 00:00:01
4: timer2, t1exp: 00:00:00, t2exp: 00:00:01
5: timer1, t1exp: 00:00:01, t2exp: 00:00:01
Final count is 5

Does this make it clearer why it's behaving the way it is?


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net