boost::asio::deadline_timer and boost::asio::io_service

classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|

boost::asio::deadline_timer and boost::asio::io_service

Boost - Dev mailing list
Hi,

I use a single thread to run 3 classes using
boost::asio::deadline_timer, the timers are managed by
boost::asio::io_service. I deliberately use a single thread to avoid
mutex, I believe those 3 timers are called exclusively by
boost::asio::io_service in a single thread, there won't be race
condition to share the objects among them, is it correct?

Thank you.

Kind regards,

- jupiter

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: boost::asio::deadline_timer and boost::asio::io_service

Boost - Dev mailing list
Hi,

Does io_service create threads for running timers? My application is
running a single thread, but if io_service creates multiple threads
for running timer, I must use the mutex or atomic lock.

Thank you.

Kind regards,

- jupiter

On 9/1/19, JH <[hidden email]> wrote:

> Hi,
>
> I use a single thread to run 3 classes using
> boost::asio::deadline_timer, the timers are managed by
> boost::asio::io_service. I deliberately use a single thread to avoid
> mutex, I believe those 3 timers are called exclusively by
> boost::asio::io_service in a single thread, there won't be race
> condition to share the objects among them, is it correct?
>
> Thank you.
>
> Kind regards,
>
> - jupiter
>

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: boost::asio::deadline_timer and boost::asio::io_service

Boost - Dev mailing list
On 2/09/2019 13:06, JH wrote:
> Does io_service create threads for running timers? My application is
> running a single thread, but if io_service creates multiple threads
> for running timer, I must use the mutex or atomic lock.

Don't top-post.


As is documented, while Asio may or may not create internal threads for
various purposes, it does guarantee that the I/O callback functions
(including timer callbacks) are only ever called on a thread which is
currently executing run() or equivalent on the same service/context.

If there is only one such thread (an "implicit strand"), then you don't
need locks to protect things that are only accessed from an I/O
callback, even if there is more than one such callback (provided that
all callbacks were registered on the same service/context).

You may still need locks to protect things that are accessed from both
callbacks and initiating functions (or elsewhere), unless you ensure
that initiating functions delegate their concurrent work to the I/O
thread via dispatch()/post().

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: boost::asio::deadline_timer and boost::asio::io_service

Boost - Dev mailing list
Thanks Gavin,

On 9/2/19, Gavin Lambert via Boost <[hidden email]> wrote:

> On 2/09/2019 13:06, JH wrote:
>> Does io_service create threads for running timers? My application is
>> running a single thread, but if io_service creates multiple threads
>> for running timer, I must use the mutex or atomic lock.
>
> Don't top-post.
>
>
> As is documented, while Asio may or may not create internal threads for
> various purposes, it does guarantee that the I/O callback functions
> (including timer callbacks) are only ever called on a thread which is
> currently executing run() or equivalent on the same service/context.

Yes, it is a single thread from my run function, there is no thread
create, so that did guarantee the single thread to run the timer one
by one in order as I original understanding.

> If there is only one such thread (an "implicit strand"), then you don't
> need locks to protect things that are only accessed from an I/O
> callback, even if there is more than one such callback (provided that
> all callbacks were registered on the same service/context).

Each timer has only one callback.

> You may still need locks to protect things that are accessed from both
> callbacks and initiating functions (or elsewhere), unless you ensure
> that initiating functions delegate their concurrent work to the I/O
> thread via dispatch()/post().

Does that mean if any callbacks to involve IO write / read, it still
need locks? What about just to copy shared global buffer to own local
buffers?

The two timer callbacks only copy contents from one globe buffer to
its own local buffer, then use own local buffer to write file, I think
that should be safe, no locks need.

Another timer callback is to read / write chip registers from a serial
line, that looks like must either lock the global buffer or copy
global buffer to a local buffer, right?

Thanks Gavin.

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: boost::asio::deadline_timer and boost::asio::io_service

Boost - Dev mailing list
On 2/09/2019 15:54, JH wrote:

> Does that mean if any callbacks to involve IO write / read, it still
> need locks? What about just to copy shared global buffer to own local
> buffers?
>
> The two timer callbacks only copy contents from one globe buffer to
> its own local buffer, then use own local buffer to write file, I think
> that should be safe, no locks need.
>
> Another timer callback is to read / write chip registers from a serial
> line, that looks like must either lock the global buffer or copy
> global buffer to a local buffer, right?

It doesn't matter how many timers there are, it only matters how many
I/O services/contexts you have and how many threads you're calling run()
on for each service.

If you're only doing things in the handlers of timer/read/write
callbacks, then they're all executing on the I/O thread and so won't be
called concurrently, so you don't need any locking.

If you have some external code which is running on another thread and
can touch the same objects (perhaps prior to calling async_write or
async_wait), then those either need protection or you need to
dispatch/post their work to the I/O thread instead (so that they cannot
run concurrently with a callback).


Bear in mind that if you're writing to that file synchronously, then it
will also prevent the other callbacks from executing for however long
that takes.  Depending on what you're doing, that may or may not be a
good thing.

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: boost::asio::deadline_timer and boost::asio::io_service

Boost - Dev mailing list
On 9/2/19, Gavin Lambert via Boost <[hidden email]> wrote:
> It doesn't matter how many timers there are, it only matters how many
> I/O services/contexts you have and how many threads you're calling run()
> on for each service.

Yes, three IO read / write, but only one thread. The thing I am not
clear was your comment, "You may still need locks to protect things
that are accessed from both callbacks".

I always thought like said in document "timers may be implemented in
terms of a single timer queue. The I/O services manage these shared
resources", if the timers callbacks / handlers exclusively run one by
one in one thread, there won't be any preambles, there won't be race
conditions, why still need lock from both callbacks?

I deliberately designed to use a single thread to avoid locks, the
comments I still need locks in a single thread, make me to rethink and
probably to redesign the single thread io_service structure I have
been embraced for many years.

> If you're only doing things in the handlers of timer/read/write
> callbacks, then they're all executing on the I/O thread and so won't be
> called concurrently, so you don't need any locking.

So I was right above comment :-).

> If you have some external code which is running on another thread and
> can touch the same objects (perhaps prior to calling async_write or
> async_wait), then those either need protection or you need to
> dispatch/post their work to the I/O thread instead (so that they cannot
> run concurrently with a callback).

No, my external code are boost libraries such as timers and
io_service, if you have already said, timers won't create threads for
me, then I won't need to worry about it. You comment here they  cannot
run concurrently with a callback is exactly I have tried design for
many years, unless I misunderstood you again :-)


> Bear in mind that if you're writing to that file synchronously, then it
> will also prevent the other callbacks from executing for however long
> that takes.  Depending on what you're doing, that may or may not be a
> good thing.

Understood, it is an embedded MCU with a single processor, satiety and
reliability are the priority in the initial design for using single
thread, when I confident that all software functions are running well
and mature, I might think to use multithreading.

Thank you Gavin.

Kind regards,

- jupiter

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: boost::asio::deadline_timer and boost::asio::io_service

Boost - Dev mailing list
On 2/09/2019 17:54, JH wrote:
> Yes, three IO read / write, but only one thread. The thing I am not
> clear was your comment, "You may still need locks to protect things
> that are accessed from both callbacks".

That's not what I said.

I said from both "callbacks" and "initiating functions".

Or in more verbose form: accessed from both of:
   1. callbacks
   2. initiating functions

The latter meaning something executed not on the callback thread --
named thus because in naive implementations usually the first read and
most writes will be initiated externally like that.

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Reply | Threaded
Open this post in threaded view
|

Re: boost::asio::deadline_timer and boost::asio::io_service

Boost - Dev mailing list
On 9/2/19, Gavin Lambert via Boost <[hidden email]> wrote:

> On 2/09/2019 17:54, JH wrote:
>> Yes, three IO read / write, but only one thread. The thing I am not
>> clear was your comment, "You may still need locks to protect things
>> that are accessed from both callbacks".
>
> That's not what I said.
>
> I said from both "callbacks" and "initiating functions".
>
> Or in more verbose form: accessed from both of:
>    1. callbacks
>    2. initiating functions
>
> The latter meaning something executed not on the callback thread --
> named thus because in naive implementations usually the first read and
> most writes will be initiated externally like that.

Well, there is no other thread other than my callbacks to run
ofstream, ifstream and Linux system read / write, I think the simple
answer is I don't need lock in a single thread, if that is correct, I
am truly relieved :-).

Thanks Gavin.

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost