How I can do non-blocking write and read from subprocess in Python 3 with use async?

Viewed 306

How I can do non-blocking write and read from subprocess in Python 3 with use async?

I created multi thread code it run subprocess than it copies stdin to stdin of subprocess and subprocess stdout to stdout and that is all.

Is it possible to write same code without use multi thread which is very cpu consuming and use of async - I am not experienced in async or very weak (very good in Python). Can you explain how to do it or present some code example how to rewrite this code?

import queue
import sys

import subprocess
import threading

import time


# copy stream into threading queue
def read_into_queue(stream, queue):
    while True:
        line = stream.readline()
        if not line:
            break
        queue.put_nowait(line)


if __name__ == '__main__':
    child_process = subprocess.Popen('cat',
                                     universal_newlines=True,
                                     stdin=subprocess.PIPE,
                                     stdout=subprocess.PIPE)

    # start thread coping stdin to child process stdin
    queue_input = queue.Queue()
    thread_input = threading.Thread(target=read_into_queue, args=(sys.stdin, queue_input), daemon=True)
    thread_input.start()

    # start thread coping child process stdout to stdout
    queue_output = queue.Queue()
    thread_output = threading.Thread(target=read_into_queue, args=(child_process.stdout, queue_output), daemon=True)
    thread_output.start()

    # check if something on queue
    while True:
        empty = 0

        try:
            input_line = queue_input.get_nowait()
            child_process.stdin.write(input_line)
            child_process.stdin.flush()
        except queue.Empty:
            empty += 1

        try:
            output_line = queue_output.get_nowait()
            sys.stdout.write(output_line)
            sys.stdout.flush()
        except queue.Empty:
            empty += 1

        # make cpu little idle
        if empty == 2:
            time.sleep(0.05)
0 Answers
Related