Boost logo

Boost :

From: Scott Woods (scottw_at_[hidden])
Date: 2005-04-03 18:35:22


Hi,

Still reading the thread and after your message I think I can
offer this as my last (again ;-) contribution and bow out after
gaining some insights. See below;

----- Original Message -----
From: "Boris" <boris_at_[hidden]>
To: <boost_at_[hidden]>
Sent: Friday, April 01, 2005 10:46 AM
Subject: [boost] Re: Re: Asynchronicity (long)

[snip]

> > Maybe there are three designs lurking here; 1 an interface that
> > wraps threads for concurrent execution of blocking functions, 2 an
> > interface that wraps queued calls to blocking functions and 3 (long
>
> If I understand correctly in 1) you have n threads for n blocking
functions
> and in 2) n threads for m blocking function with n < m? So in 2) you call
> blocking functions one after the other?
>
> > description omitted)
> > mine :-)
>
> That was the posting which ended with "Confused?", right? ;)

For me the possible architectures now boil down to;

1) A pool of threads available to assume responsibility for concurrent
execution of a specified function. The calling code may block (i.e. wait)
 on "all threads busy" or return immediately with an error condition.
2) A thread taking its work from a queue.
3) Mine (AKA Confused)

There are of course some large number of combinations and permutations
possible.

> And I have been wondering if it makes sense to build a network library
with
> asynchronous support on top of an asynchronicity library as an
> implementation of the network library can not make use then of I/O APIs
> which seem to be much better supported by different operating systems than
> asynchronous APIs. A better solution could be to agree upon some rules
about
> how methods (which support asynchronous operations) should be called and
> what their signatures should look like. Eg. in .NET you can always create
a
> delegate and call BeginInvoke() to execute a blocking function in a
thread.
> But when you have a socket you call BeginAccept() which has a similar
> signature as BeginInvoke(). For the application developer no difference -
> for the library developer the chance to implement BeginAccept() more
> efficiently than with a delegate and BeginInvoke() which would just create
> another thread.

Understood.

IMO this thread is attempting to wrap specific code fragments (i.e. calls to
blocking functions) with some mechanism that allows the caller to continue
execution, dealing with the "return" at some later, optimal moment (when the
underlying operation actually completes).

The specific plumbing underneath the wrapper (best use of threads, signaling
mechansims and queues) seems secondary to me.

This certainly removes blocking calls from application code - this thread
is "on track" :-) But for me this is only part way there.

A library that wraps blocking calls in a non-blocking framework reinforces
a style of programming. There is a "main" thread that needs to be "always
ready"
(not blocked). It spends its time waiting for the next event (i.e. callback)
and
responding by creating more wrappers around blocking operations (amongst
other things). This is a simplification but one that hopefully helps make my
point.

What such a library doesnt attempt to do is provide a framework for the
async
processing of a "block stream" whether that be a disk file of a network
connection.

Because that processing is actually what the application is about, that is
where
my thoughts are headed. Software written using the library sketched above
must
implement its own custom framework for carrying state from one callback
the next. This is do-able but for me seems to be coding "on the back foot".

My directions have been influenced by the work of D. Schmidt and his Active
Objects as well as others (e.g. SDL). In the world of AO's the creation of a
delegate
is fulfilled by sending of a message. The AO world is symmetric; there is no
"main"
thread that supervises the scheduling of concurrent activities. Messages are
standalone objects (i.e. effectively call-by-value) and messages can "fall
into
the void" (specifically occurring when a call is made, and queued, to an
object
that disappears before the related processing occurs). I mention such points
as related questions have arisen in this thread. In the AO world these
questions
are also answered ;-)

An AO is the context for the processing of a "block stream".

Maybe the aync-wrapper-lib will evolve into something akin to AO's? Maybe
AO's will be nicely implementable over that lib? Maybe these two directions
are utterly distinct and independently useful?

These questions are too big for me :-)

Cheers,
Scott


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk