is there enough information?
castironpi at gmail.com
castironpi at gmail.com
Wed Mar 5 05:09:38 CET 2008
On Mar 4, 5:59 pm, David Bolen <db3l.... at gmail.com> wrote:
> Dennis Lee Bieber <wlfr... at ix.netcom.com> writes:
> > On Mon, 3 Mar 2008 08:11:43 -0500, Jean-Paul Calderone
> > <exar... at divmod.com> declaimed the following in comp.lang.python:
> >> I'm not sure, but you seem to be implying that the only way to use Windows'
> >> asynchronous I/O APIs is with threads. Actually, it is possible (and Twisted
> >> allows you) to use these as well without writing a threaded application.
> > I only pointed out that, on Windows, one can not use the common
> > /select()/ function with files. And one rarely sees examples of coding a
> > Twisted-style (emphasis on style) asynchronous callback system mixing
> > files and network sockes using the Windows-specific API.
> > If using threads, the Windows asynchronous I/O isn't needed... let
> > the thread block until the I/O completes, then transfer the data (or a
> > message that the data is available) back to the main processing
> > thread...
> You're probably right that it's rare, but when needed, using the
> Windows asynchronous/overlapping API can provide a better solution
> than blocking threads depending on the needs at hand, and without
> involving any callbacks or Twisted-style programming.
> An example of mine is high performance serial port handling as part of
> a custom FHSS wireless adapter with a serial port interface to the PC.
> In this case, minimizing I/O latency was crucial since delays could
> mean missing a broadcast timeslot (about 15ms) on the wireless
> network. A serial port isn't a disk file, but certainly a "file" in
> the context of Windows handles.
> Early implementations used independent threads for reading/writing to
> the serial port and blocking during such operations, but that turned
> out to have an undesirable amount of latency, and was also difficult
> to interrupt when the threads were in a blocked condition.
> Instead I created a single thread that had a loop using overlapped I/O
> simultaneously in each direction as well as native Windows event
> objects for aborting or signaling that there was additional data to be
> written (the pending read I/O handled the read case). The main loop
> was just a WaitForMultipleObjects to handle any of the I/O completion
> indications, requests for more I/O or aborts. It was very high
> performing (low latency) with low CPU usage - measurably better than a
> multi-threaded version.
> Communication with the rest of the application was through a
> thread-safe bi-directional buffer object, also using native Win32
> event objects. It worked similar to a queue, but by using the native
> event objects I didn't have the performance inefficiencies for reads
> with timeouts of the Python objects. The underlying Python primitives
> don't have the timeout capability built in, so reads with timeouts get
> implemented through checks for data interspersed with increasing
> sleeps, which adds unnecessary latency.
> Anyway, it worked extremely well, and was a much better fit for my
> needs than a multi-threaded version with blocking I/O, without it
> having to be Twisted-style.
> -- David- Hide quoted text -
> - Show quoted text -
How does it work? From reading threading.py, _Condition.wait()
acquires self.lock() too many times-- that is, once to call wait
("cannot wait on un-aquired lock"), and once after--- are "all
waiters" waiting back at self.acquire, just to make it to
self.notify... and only one at a time at that!? Don't waiters have to
release before another waiter can go?
More information about the Python-list