Python, Tkinter and popen problem

norseman norseman at hughes.net
Fri May 29 19:48:31 EDT 2009


Piet van Oostrum wrote:
>>>>>> norseman <norseman at hughes.net> (n) wrote:
> 
>> n> I have tried both and Popen2.popen2().
>> n> os.popen runs both way, contrary to docs.
> 
> What do you mean `os.popen runs both way'?

It reads from child while console writes directly to child -  thus 
eliminating the problem of coding a pass through from master.

> 
>> n> # master.py
>> n> import os
>> n> #                both lines work same
> 
> Of course, because 'r' is the default, and the bufsize for reading the
> pipe only influences the performance.
> 
>> n> #xx= os.popen("/mnt/mass/py/z6.py").readlines()
>> n> xx= os.popen("/mnt/mass/py/z6.py",'r',1).readlines()
>> n> #                I had hoped small buffer would force a sync (flush())
>> n> #                No such luck.
> 
> First, there is a difference between sync and flush. flush is writing
> out any output that is buffered in the application program for that
> file. Sync is writing out buffers (cache) in the operating system (to the
> disc, network connection or similar). We are talking here about
> flushing, not syncing. As we deal with a pipe, sync is not applicable.
> 
> Furthermore, whatever you do in the master program, such as setting the
> buffer size has nothing to do with what happens in the child, so it will
> not influence the flushing behaviour of the child. The only way to
> influence that would be to use a pty instead of a pipe, because most
> code uses a different buffering strategy for ttys and ptys compared to
> files and pipes.
> 
> The next error in your program is that you use readlines()
> This reads ALL input from your pipe before it proceeds. So essentially
> it waits until the child process is finished and therefore gives you the
> impression that it doesn't flush(). But it is not the child that is the
> problem it is your master.
> 
> What you should do is take the pipe and do a readline()/print loop.
> 
> #xx= os.popen("/mnt/mass/py/z6.py")
> 
> # popen is deprecated. Replace with subprocess:
> from subprocess import Popen, PIPE
> xx = Popen(["/mnt/mass/py/z6.py"], stdout=PIPE).stdout
> 
> while True:
>     line = xx.readline()
>     if not line: break
>     print "\t" + line,
> 
> The obvious:
> 
> for l in xx:
>     print "\t" + l,
> 
> doesn't work as the iterator for a file, including pipes, does a
> read ahead (see the doc on file.next()) and therefore is not suitable for
> interactive use.
> 
>> n> The direct question comes back to:
> 
>> n> How does one force a sync or flush() to take effect in Python with
>> n> Tkinter in use? Or just in Python period. The keyword being force.
> 
> So it should be clear by now that the answer is to use flush().
> And make sure you read AND process the flushed output in a proper way.
> 
> By the way, you have a nasty habit of using very unclear language to
> pose your problems in this newsgroup/mailing list, instead of writing a
> concise description and giving small examples of what code causes the
> problem. This makes it extremely difficult to help you. I had to read
> your messages at least 5 times to get an idea of what you were doing and
> what the problem was that you wanted to solve.
> 
> Maybe you are dyslectic or something similar, in which case I apologize.
> But anyway, I think you should learn to express yourself more clearly.
> There are also courses for that.
===============================

"...
> doesn't work as the iterator for a file, including pipes, does a
> read ahead (see the doc on file.next()) and therefore is not suitable
> for interactive use.
..."

If I understand you the above can be stated as:

The above does not work as an iterator for any file type, including
pipes, but it does do read aheads .... and therefore is not suitable for
interactive use.

If that is correct then read ahead is simply buffered file reads (grab a
chunk, parcel it out on demand) - yes?

As for "... not suitable for interactive ..." Really?  Except for
special purpose use the current interactive components are all buffered
for read ahead use.  Check the actual code for your keyboard, your mouse
and so forth. It's the read ahead that allows faster time to completion.
It's why C-code has the putch function.


Yes - Sync IS the bigger hammer!  If that is what is needed - so be it.
All character readers (byte at a time) should obey a flush(). Depending
on type, code for the reader controls whether or not it flushes
incomplete "lines" in the in-buffer(s). Proper implementation limits 
lost data on system crash.
In trying to use flush at the master side I keep getting messages
indicating strings (completed or not) are not flushable.  Strange 
practice.

---
from subprocess import Popen, PIPE
xx = Popen(["z6.py"], stdout=PIPE).stdout

while True:
     line = xx.readline()
     if not line: break
     print "\t" + line,
---
DOES WORK on Python 2.5.2 on Slackware 10.2 - THANK YOU VERY MUCH!!!
Isn't working on Windows. error message comes as one of two forms.
   1- %1 not found       #as shown above
   2- file not found     #as ...["python z6.py"]...
         same            #as #2 even with full paths given
I get the impression subprocess ignores system things on Windows.
The routines it purposes to replace do use them.  At any rate, 
subprocess is NOT consistent across platforms.

Some questions:
	1) "...], stdout=PIPE).stdout
                    ^            ^  why the double use?
	2) "if not line: break"  what tells what to look for EOL
                                    or is the use of 'line' missleading?
                                    is it a byte at a time output?
                                  how much CPU usage does the loop use?
                                  is there something in that loop that
                                    uses the system pipe triggers to
                                    reduce excessive CPU waste or does it
                                    constantly poll?  If so where does
                                    what code get put to signal (or set)
                                    the courtesy semiphores so it does
                                    not hog the system?


Again - Thank you for something that works.

Steve




More information about the Python-list mailing list