[MUD-Dev] Re: lurker emerges
T. Alexander Popiel
popiel at snugharbor.com
Mon Aug 10 21:45:05 CEST 1998
In message: <35CFBD79.68748E69 at freehold.crocodile.org>
Vadim Tkachenko <vt at freehold.crocodile.org> writes:
>Preserved for clarity
Again...
>
>> Blocking I/O: you make a library/system call requesting an I/O
>> operation of a given size. The call does not return until the
>> entire operation completes for the entire size requested,
>> regardless of delays incurred. Under some implementations,
>> external (and only external) sources may interrupt the call.
>> Under no circumstances is your program able to do other work
>> while waiting for the I/O to complete.
>>
>> Non-blocking I/O: you make a library/system call requesting
>> an I/O operation of a given size. The call always returns
>> 'immediately' (after minimal processing of the request,
>> responding with whatever data is already on hand), with an
>> indication of how much I/O was actually performed. In some
>> implementations (UNIX sockets), no further processing is done
>> without additional request. In other implementations (Amiga,
>> apparently, and some of the old mainframes), when the remainder
>> of the requested I/O is completed, the calling program is
>> informed. In both cases, a _separate_ library/system call is
>> available to wait until more I/O is possible or I/O completes
>> (depending on flavor).
>
>Okay, now I see that I meant the same definitions, although have a
>different viewpoint.
>
>For last 2 years I'm thinking in Java, before that I'd been thinking in
>C++ for 6 years, 2 of which were preemptive and multithreaded, before
>that, it was Windows.
For reference, I only started Java two years ago, and before and
during that, I've been a big UNIX and C (_not_ C++) fan. Java is
not my first exposure to multithreading issues (I also do MUSHcode
which exhibits many of the same problems), but I generally view
multithreading in terms of the large amount of overhead it brings.
>Now, I agree that UNIX may not (I'm not really strong in C++ in UNIX)
>and Java does not have asynchronous I/O as you describe it. However, I
>was doing the stuff mostly top-to-the-bottom and don't really see a
>problem here. Let me draft it (I guess, it's pretty obvious):
>
>ACT is the Asynchronous Completion Token (Design patterns...), has
>read_count field and a semaphore.
>
>ACT asyncread( buffer, how_much_do_I_want, boolean all_async );
>
>OK, so what I have is some read performed at once (no sense in async
>read if I know the absolute minimum I want), and then I know how much
>did I read - the ACT has it. Then, I can go out and do my stuff, and
>when I'm ready I may go out and wait for the completion semaphore (let
>me emphasise, _event_ semaphore).
If I'm reading this correctly, your asyncread() creates a semaphore,
spawns a thread, associates the two, and returns immediately. The
spawned thread does the actual blocking read, then notifies the
semaphore and exits.
To recreate my non-blocking I/O library call, you've added the
overhead of semaphore creation and destruction (and a possible
semaphore leak if the caller does not dispose of the semaphore
properly), and thread creation and destruction, all to end up
with something functionally equivalent to what I wanted in the
first place. Personally, I don't see this as a win. Especially
on systems (like SunOS 4.1.3) which don't support threading at
all, making what you suggest well nigh impossible.
>So, on the API level - what's the difference between the _library_ call
>and the simple piece of code I'm talking about? Agreed, the former may
>be _much_ more effective, but if you're going to production, you need
>the _scalable_ solution anyway, and if it really bothers you, go to the
>platform which does have the stuff you mentioned and make it native, in
>Java case.
I think the only difference is in performance and the a stylistic
preference in choice of primitives. I prefer async primitives,
because sync can be built on async with trivial performance loss
(two routine calls (request, wait) instead of one), while async
can be built on sync only with lots of other cruft (semaphores,
threads) and large performance loss.
>> The most important distinction in my mind is the ability (or
>> lack thereof) to separate the request and the wait for request
>> completion.
>
>Nah, the Asynchronous Completion Token is a solution in this case.
A solution which only works if you have a multithreaded environment...
which I don't. :-(
- Alex
More information about the mud-dev-archive
mailing list