non-blocking PIPE read on Windows

Durumdara durumdara at gmail.com
Mon Jul 31 03:57:15 EDT 2006


Hi !

If you don't want to use MS-specific things, you can use the normal pipes.
See this code. If you want to use non-blocking version, you need to create a
thread that handle the reads/writes.

import os, sys, time, binascii, cPickle

bpath,bname=os.path.split(sys.argv[0])

def Log(Msg,IsMaster,First=False):
    fn=sys.argv[0]+'.'+['c','m'][int(IsMaster)]+'.log'
    mode='aw'[int(First)]
    f=open(fn,mode)
    f.write('\n%s:\n'%time.time())
    f.write('%s\n'%Msg)
    f.flush()
    f.close()

def ReadTextPacket(SourceStream):
    packet=SourceStream.read(6)
    psize=int(packet)
    packet=SourceStream.read(psize)
    return packet

def WriteTextPacket(DestStream,Packet):
    Packet=str(Packet)
    DestStream.write('%06d'%len(Packet))
    DestStream.write(Packet)
    DestStream.flush()

'''
def ReadBinPacket(SourceStream):
    txtpacket=ReadTextPacket(SourceStream)
    pckpacket=binascii.unhexlify(txtpacket)
    obj=cPickle.loads(pckpacket)
    return obj

def WriteBinPacket(DestStream,Obj):
    pckpacket=cPickle.dumps(Obj)
    txtpacket=binascii.hexlify(pckpacket)
    WriteTextPacket(DestStream,txtpacket)
'''

if 'C' in sys.argv:
    #Log('Client started',0,1)
    while 1:
        #Log('Waiting for packet',0,0)
        data=ReadTextPacket(sys.stdin)
        #Log('Packet received',0,0)
        #Log('The packet is: %s'%([data]),0,0)
        #Log('Print the result',0,0)
        WriteTextPacket(sys.stdout,"Master wrote: %s"%([data]))
        if data.strip()=='quit':
            #Log('Quit packet received',0,0)
            break
    #Log('Client finished',0,0)
else:
    #Log('Master started',1,1)
    #Log('Start subprocess',1,0)
    import time
    st=time.time()
    child_stdin,child_stdout=os.popen2(r'c:\python24\python.exe %s
C'%(bname))
    for i in range(1000):
        #Log('Send packet',1,0)
        WriteTextPacket(child_stdin,['Alma'*100,i])
        #Log('Waiting for packet',1,0)
        s=ReadTextPacket(child_stdout)
        #Log('Packet is: %s'%([s]),1,0)
        #Log('Print packet',1,0)
        #print "Client's answer",[s]
        import time
        time.sleep(0.1)
    #Log('Send packet',1,0)
    WriteTextPacket(child_stdin,'quit')
    #Log('Waiting for packet',1,0)
    s=ReadTextPacket(child_stdout)
    #Log('Packet is: %s'%([s]),1,0)
    #Log('Print packet',1,0)
    #print "Client's answer",[s]
    #Log('Master finished',1,0)
    print time.time()-st

dd


2006/7/28, Dennis Lee Bieber <wlfraed at ix.netcom.com>:
>
> On 27 Jul 2006 22:26:25 -0700, "placid" <Bulkan at gmail.com> declaimed the
> following in comp.lang.python:
>
> >
> > readline() blocks until the newline character is read, but when i use
> > read(X) where X is a number of bytes then it doesnt block(expected
> > functionality) but i dont know how many bytes the line will be and its
> > not constant so i cant use this too.
> >
> > Any ideas of solving this problem?
> >
>         Use a thread that reads one character at a time; when it sees
> whatever signals "end of line" (it sounds like you're reading a progress
> bar implemented via <cr>overwrite). Combine the characters into a
> string, return the string to the main program via a queue.
>
>         If there is no such "end of line" character, but there IS a
> noticeable delay between "writes", a more complex method might suffice
> -- in which one thread does the byte reads, setting a time value on each
> read; a related thread then does a sleep() loop, checking the "last read
> time" against the pause length -- if close enough to the pause duration,
> combine and return...
>
>         Alternatively, take a good old style terminal keyboard (a VT100
> Tempest-rated model should be ideal), and use it to beat Bill Gates over
> the head until he agrees to push a high-priority upgrade to the command
> line I/O system... or makes files work with select() (so you can combine
> the time-out with the byte read)
>
> --
>         Wulfraed        Dennis Lee Bieber               KD6MOG
>         wlfraed at ix.netcom.com           wulfraed at bestiaria.com
>                 HTTP://wlfraed.home.netcom.com/
>         (Bestiaria Support Staff:               web-asst at bestiaria.com)
>                 HTTP://www.bestiaria.com/
> --
> http://mail.python.org/mailman/listinfo/python-list
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-list/attachments/20060731/f6e6d60e/attachment.html>


More information about the Python-list mailing list