How to create non-blocking continuous reading from `stdin`?

前端 未结 5 1603
小蘑菇
小蘑菇 2021-02-04 19:27

I have a single process, which has been created like this:

p = subprocess.Popen(args   = \'./myapp\',
                     stdin  = subprocess.PIPE,
                     


        
5条回答
  •  [愿得一人]
    2021-02-04 19:42

    For everything working fine you have to flush output in main process (p.stdout) and subprocess (sys.stdout) .

    communicate does both flush:

    • it flush the p.stdin when closing it
    • it wait the sys.stdout output to be flushed (just before exiting)

    example of working main.py

    import subprocess,time
    import sys
    p = subprocess.Popen(args   = ['python3', './myapp.py'],
                         stdin  = subprocess.PIPE,
                         stdout = subprocess.PIPE,
                         universal_newlines=True)
    
    time.sleep(0.5)
    p.stdin.write('my message\n')
    p.stdin.flush()
    #print("ici")
    for i,l in  enumerate(iter(p.stdout.readline, ''),start=1):
    
        print("main:received:",i,repr(l))
        if i == 6:
            break
        print("mainprocess:send:other message n°{}".format(i))
        p.stdin.write("other message n°{}\n".format(i))
        p.stdin.flush()
    
    print("main:waiting for subprocess")
    p.stdin.close()    
    p.wait()
    

    example of myapp.py import queue,threading,sys,time,rpdb

    q = queue.Queue()
    def get_input():
        for line in iter(sys.stdin.readline, ''):
            q.put(line)
        sys.stdin.close()
    
    threading.Thread(name   = 'input-getter',
                     target = get_input).start()
    for i in range(6):
        try:
            l= q.get_nowait()
            print('myapp:input:', l,end="")
            sys.stdout.flush()
    
        except queue.Empty:
            print("myapp:no input")
            sys.stdout.flush()    
            time.sleep(1)
    

    result:

    main:received: 1 'myapp:no input\n'
    mainprocess:send:other message n°1
    main:received: 2 'myapp:input: my message\n'
    mainprocess:send:other message n°2
    main:received: 3 'myapp:input: other message n°1\n'
    mainprocess:send:other message n°3
    main:received: 4 'myapp:no input\n'
    mainprocess:send:other message n°4
    main:received: 5 'myapp:input: other message n°2\n'
    mainprocess:send:other message n°5
    main:received: 6 'myapp:input: other message n°3\n'
    main:waiting for subprocess
    

提交回复
热议问题