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

前端 未结 5 1606
小蘑菇
小蘑菇 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:45

    Trying to investigate your program, I wrote my own "continually stream stuff to cat and catch what it returns" program. I didn't implement the subprocess side of it, but hopefully the structure is similar.

    This line is very odd about your program...

    for line in iter(sys.stdin.readline, ''):
        q.put(line)
    sys.stdin.close()
    

    That looks an awful lot like

    for line in stdin:
        q.put(line)
    

    Note that the loop is going to end when the pipe is closed and there's no need to re-close it afterwards.

    If you need to continously asynchronously read stdin, you should be able to construct a reading thread near-identical to child_reader in the code below. Just replace child.stdout with stdin.

    import subprocess
    import threading
    import random
    
    # We may need to guard this?
    child = subprocess.Popen('cat', stdout=subprocess.PIPE, stdin=subprocess.PIPE)
    
    # Continuously print what the process outputs...
    def print_child():
        for line in child.stdout:
            print(line)
    
    child_reader = threading.Thread(target = print_child)
    child_reader.start()
    
    for i in range(10000):
        chars = 'ABC\n'
        child.stdin.write(random.choice(chars).encode())
    
    # Send EOF.
    # This kills the cat.
    child.stdin.close()
    
    # I don't think order matters here?
    child.wait()
    child_reader.join()
    

提交回复
热议问题