threading

Chris Angelico rosuav at gmail.com
Wed Apr 9 10:44:52 EDT 2014


On Thu, Apr 10, 2014 at 12:30 AM, Frank Millman <frank at chagford.com> wrote:
>
> "Chris Angelico" <rosuav at gmail.com> wrote in message
> news:CAPTjJmqwhb8O8vq84mMTv+-Rkc3Ff1AQDXe5cs8Y5gY02kHyNg at mail.gmail.com...
>> On Wed, Apr 9, 2014 at 11:23 PM, Frank Millman <frank at chagford.com> wrote:
>>
>>> How does one distinguish betwen 'blocking' and 'non-blocking'? Is it
>>> either/or, or is it some arbitrary timeout - if a handler returns within
>>> that time it is non-blocking, but if it exceeds it it is blocking?
>>
>> No; a blocking request is one that waits until it has a response, and
>> a non-blocking request is one that goes off and does something, and
>> then comes back to you when it's done.
>
> Does reading from disk count as blocking? Strictly speaking I would have
> thought 'yes'.

What the operation actually *is* is quite immaterial. Reading from the
disk can be done as blocking or non-blocking; if you simply open a
file and call its read() method, that'll block by default (the open()
call can block, too, but you asked about reading). When you ask for
something to be done and expect a return value with the result, that
implies a blocking operation. Even simple work like floating-point
addition can be blocking or nonblocking; I learned some of the basics
of the 8087 coprocessor and how to do assembly-language floating
point, and it was, by default, a non-blocking operation - you say "Go
do this", and then you say "FWAIT" to block until the coprocessor is
done. But normally you want to be able to write this:

a = 12.3
b = 45.6
c = a + b
print("The sum is:",c)

rather than this:

add_async(a, b, lambda c: print("The sum is:",c))

> In other words, non-blocking implies that everything required to pass off
> the request to a handler and be ready to deal with the next one must already
> be in memory, and it must not rely on communicating with any outside
> resource at all. Is this correct?

Nope. It simply requires that communicating with an outside resource
be done asynchronously. You fire off the request and either check for
its completion periodically (polling) or get a notification when it's
done (callback, usually).

>> def nonblocking_query(id):
>>    print("Finding out who employee #%d is..."%id)
>>    def nextstep(res):
>>        print("Employee #%d is %s."%(id,res[0].name))
>>    db.asyncquery(nextstep, "select name from emp where id=12345")
>>
>
> In this example, what is 'db.asyncquery'?
>
> If you mean that you have a separate thread to handle database queries, and
> you use a queue or other message-passing mechanism to hand it the query and
> get the result, then I understand it. If not, can you explain in more
> detail.

It's an imaginary function that would send a request to the database,
and then call some callback function when the result arrives. If the
database connection is via a TCP/IP socket, that could be handled by
writing the query to the socket, and then when data comes back from
the socket, looking up the callback and calling it. There's no
additional thread here.

> If I have understood correctly, then is there any benefit at all in my going
> async? I might as well just stick with threads for the request handling as
> well as the database handling.

Threads are a convenient way to handle things, but they're an
alternative. You generally do one or the other. Occasionally you'll
use a bit of both, maybe because your database handler can't work
asynchronously, but ideally you shouldn't need to mix and match like
that.

I'm oversimplifying horribly, here, but hopefully helpfully :)

ChrisA



More information about the Python-list mailing list