On Mar 4, 5:59 pm, David Bolen <[EMAIL PROTECTED]> wrote: > Dennis Lee Bieber <[EMAIL PROTECTED]> writes: > > > > > > > On Mon, 3 Mar 2008 08:11:43 -0500, Jean-Paul Calderone > > <[EMAIL PROTECTED]> 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? -- http://mail.python.org/mailman/listinfo/python-list