Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does inside a strand mean?

I'm currently trying to get my hands on boost::asio strands. Doing so, I keep reading about "invoking strand post/dispatch inside or outside a strand". Somehow I can't figure out how inside a strand differs from through a strand, and therefore can't grasp the concept of invoking a strand function outside the strand at all.

Probably there is just a small piece missing in my puzzle. Can somebody please give an example how calls to a strand can be inside or outside it?

What I think I've understood so far is that posting something through a strand would be

m_strand.post(myfunctor);

or

m_strand.wrap(myfunctor);
io_svc.post(myfunctor); 

Is the latter considered a call to dispatch outside the strand (as opposed to the other being a call to post inside it)? Is there some relation between the strand's "inside realm" and the threads the strand operates on?

If being inside a strand simply meant to invoke a strand's function, then the strand class's documentation would be pointless. It states that strand::post can be invoked outside the strand... That's precisely the part I don't understand.

like image 414
starturtle Avatar asked Jun 15 '16 09:06

starturtle


People also ask

What's is the meaning of strand?

/strænd/ a fiber or group of fibers twisted together that form one part of a length of rope, cord, thread, etc., or a single string, hair, or line of objects: a strand of hair.

What is an example of a strand?

A single hair, a noodle, even a line of thought — any of these things could be called a strand, a long thin length of something. The noun strand describes things that are long and thin like a rope, or a strand of spaghetti, hair, or thread.

What does strands mean in hair?

countable noun. A strand of something such as hair, wire, or thread is a single thin piece of it.

What does strand mean in literature?

strand - a poetic term for a shore (as the area periodically covered and uncovered by the tides)


1 Answers

Even I had some trouble in understanding this concept, but became clear once I started working on libdispatch. It helped me map things with asio better.

Now lets see how to make some sense out of strand. Consider strand as a serial queue of handlers which needs to be executed.

Now, where does these handlers get executed ? Within the worker threads.

Where did these worker threads come from ? From the io_service object you passed while creating the strand. Something like:

asio::strand s(io_serv_obj);

Now, as you must be knowing, the io_service::run can be called by a single thread or multiple threads. The threads calling the run method of the io_serv_obj are the worker threads for that strand in our case. So, it could be either single threaded or multithreaded.

Coming back to strands, when you post a handler, that handler is always enqueued in the serial queue which we talked about. The worker threads will pick up the handler from the queue one after the other.

Now, when you do a dispatch, asio does some optimization for you:

  1. It checks whether you are calling it from inside one of the worker thread or from some other thread (maybe of some other io_service instance). When it is called outside the current execution context of the strand, thats when it is called outside the strand. So, in the outside case, the dispatch will just enqueue the handler like post when there are other handlers waiting in the queue or will call it directly when it can guarantee that it will not be called concurrently with any other handler from that queue that may be running in one of the worker threads at that moment.

UPDATE: As noted in the comments section, inside means called within another handler i.e for eg: I posted a handler A and inside that handler, I am doing a dispatch of another handler. Now, as would be explained in #2, if there are no other handlers waiting in the strands serial queue, the dispatch handler will be called synchronously. If this condition is not met, that means, the dispatch is called from outside.

  1. Now, if you call dispatch from outside of the strand i.e not within the current execution context, asio checks its callstack to see if any other handler present in its serial queue is running or not. If not, then it will directly call that handler synchronously. So, there is no cost of enqueueing the handler (I think no extra allocation will be done as well, not sure though).

Lets see the documentation link now:

s.dispatch(a) happens-before s.post(b), where the former is performed outside the strand

This means that, if dispatch was called from some outside the current run OR there are other handlers already enqueued, then it needs to enqueue the handler, it just cannot call it synchronously. Since its a serial queue, a will get executed before b.

Had there been another call s.dispatch(c) along with a and b but before a and b(in the mentioned order) enqueued, then c will get executed before a and b, but in no way b can get executed before a.

Hope this clears your doubt.

like image 102
Arunmu Avatar answered Nov 03 '22 00:11

Arunmu