[python-win32] PythonWin and calling functions across threads

Mark Hammond mhammond at skippinet.com.au
Thu Dec 30 02:22:23 CET 2004


Internally, Pythonwin uses a queue for all sys.stdout writing, to ensure the
actual window update only ever happens on the main thread (which is a
requirement of Windows).

To get a "smooth" effect, Pythonwin queues output until a newline is seen.
This is probably the reason.  To change this behaviour, open
pywin\framework\winout.py, and find the line:

def __init__(self, title=None, defSize=None, queueing = flags.WQ_LINE ...

Change queueing to flags.WQ_NONE - this should dump output as it arrives,
but will often make the output appear "chunky".

I'd (obviously) be open to patches that exposed this via the UI, if it was
felt necessary.

Mark.

> -----Original Message-----
> From: python-win32-bounces at python.org
> [mailto:python-win32-bounces at python.org]On Behalf Of Steven Bethard
> Sent: Thursday, 30 December 2004 9:05 AM
> To: python-win32 at python.org
> Subject: [python-win32] PythonWin and calling functions across threads
>
>
> I posted this originally to the python-list[1], but then discovered
> that my problem only occurs in PythonWin.  Any help would be
> appreciated:
>
> [1]
> http://mail.python.org/pipermail/python-list/2004-December/257666.html
> -------- Original Message --------
> Subject: calling functions across threads
> Date: Wed, 29 Dec 2004 17:35:41 GMT
> From: Steven Bethard <steven.bethard at gmail.com>
> Newsgroups: comp.lang.python
>
> I'm playing around with some threading stuff right now, and
> I'm having a
> little trouble calling a function from one thread that
> affects another.
>  Here's my setup:
>
> py> import os, threading, time
> py> def write(file_in, input_lines):
> ...     for line in input_lines:
> ...         time.sleep(0.5)
> ...         file_in.write(line)
> ...         file_in.flush()
> ...     file_in.close()
> ...
> py> def read(file_out, output_list):
> ...     while True:
> ...         line = file_out.readline()
> ...         if not line:
> ...             break
> ...         output_list.append(line)
> ...
> py> def runthreads(lst):
> ...     file_in, file_out, file_err = os.popen3('cat')
> ...     write_thread = threading.Thread(
> ...         target=write, args=(file_in,
> ...                             ['%s\n' % x for x in range(10)]))
> ...     read_thread = threading.Thread(target=read,
> ...                                    args=(file_out, lst))
> ...     write_thread.start()
> ...     read_thread.start()
> ...     write_thread.join()
> ...     read_thread.join()
> ...
>
> Basically, I start one thread to read and one thread to write (from a
> os.pipe).  This all works fine for me:
>
> py> lst = []
> py> runthreads(lst)
> py> lst
> ['0\n', '1\n', '2\n', '3\n', '4\n', '5\n', '6\n', '7\n', '8\n', '9\n']
>
> I run into a problem though when I try to call an update method every
> time I read a line:
>
> py> class updatinglist(list):
> ...     def __init__(self, updater):
> ...         super(updatinglist, self).__init__()
> ...         self.updater = updater
> ...     def append(self, item):
> ...         super(updatinglist, self).append(item)
> ...         self.updater(len(self))
> ...
> py> def update(i):
> ...     print i
> ...
> py> lst = updatinglist(update)
> py> runthreads(lst)
> 1
> 2
> 3
> 4
> 5
> 6
> 7
> 8
> 9
> 10
> py> lst
> ['0\n', '1\n', '2\n', '3\n', '4\n', '5\n', '6\n', '7\n', '8\n', '9\n']
>
> I get the correct output, but if you run this yourself,
> you'll see that
> the numbers 1 through 10 aren't printed in sync with the writes (i.e.
> every half second); they're all printed at the end.  Could someone
> explain to me why this happens, and how (if possible) I can get the
> numbers printed in sync with the appends to the list?
>
> Thanks,
>
> Steve
> _______________________________________________
> Python-win32 mailing list
> Python-win32 at python.org
> http://mail.python.org/mailman/listinfo/python-win32



More information about the Python-win32 mailing list