Boost logo

Boost Users :

Subject: Re: [Boost-users] playing around with tutorial codes to understand ioservice
From: Ozgur Ozturk (ozgur7_at_[hidden])
Date: 2009-07-11 18:35:54


Hi,
      Thanks Zachary, yes, I have made a typo, thanks for pointing to it,
and for the explanation.
      But it I have the same question for your code since we have a similar
(interleaved) output.
What I understood was, when we call io.run, main thread is suspended until
things assigned to it finishes.
(that is why in the examples the final count is not printed before an
io.run() completes, right?!)
so how come io2.run() is invoked from main thread (before io.run() finishes)
(and we can get interleaved results)?
Something I must be getting wrong.

TIA,
Best regards,
Ozgur (Oscar) Ozturk
www.DrOzgur.com
+1 (614) 805-4370

On Sat, Jul 11, 2009 at 5:33 PM, Zachary Turner <divisortheory_at_[hidden]>wrote:

> 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 mailing list
> Boost-users_at_[hidden]
> http://lists.boost.org/mailman/listinfo.cgi/boost-users
>



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