Иногда возникает блокировка при использовании select.select в родительских и дочерних процессах - PullRequest
0 голосов
/ 03 апреля 2020

Привет У меня есть вопрос, который беспокоил меня в течение 2 недель. Я пытался решить ее, но теперь все еще иногда сталкиваюсь с проблемой тупика. Мой подробный вопрос заключается в следующем, и спасибо за вашу помощь.

Есть один родительский процесс и три дочерних процесса. Родительский процесс используется для объединения трех программ командной строки, которые можно рассматривать как этап предварительной обработки, основной обработки и этапа последующей обработки.

# Parent process

pre_process = subprocess.Popen("python pre1.py | python pre2.py | python pre3.py", stdin=subprocess.PIPE, stdout=subprocess.PIPE, shell=True)
main_process = subprocess.Popen("python main.py", stdin=subprocess.PIPE, stdout=subprocess.PIPE, shell=True)
post_process = subprocess.Popen("python post1.py | python post2.py", stdin=subprocess.PIPE, stdout=subprocess.PIPE, shell=True)

while True:
    read_stdouts, _, _ = select.select([pre_process.stdout, main_process.stdout, post_process.stdout], [], [], 0)

    for read_stdout in read_stdouts:
        if read_stdout == pre_process.stdout:
            # Do something
            print(output1, file=main_process.stdin)
        elif read_stdout == main_process:
            # Do something
            print(output2, file=post_process.stdin)
        else:
            # Do something and write to socket

В родительском процессе я использовал subprocess.Popen в Python, чтобы создать три подпроцесса и установить stdin / stdout в PIPE. select.select использовался для мониторинга и пересылки сообщений от одного шага к следующему шагу.

В дочернем процессе основной обработки я также использовал select.select для мониторинга входящего сообщения. Временное окно настроено для сбора сообщений за фиксированный период времени и их совместной обработки за один раз для повышения эффективности.

# Main processing child process

while True:
    inputs = []
    while True:
        if select.select([sys.stdin], [], [], 0)[0]:
            line = sys.stdin.readline()
            inputs.append(line.strip())
        else:
            break

    if len(inputs) < 1:
        time.sleep(0.5)
        continue

    # Time-consuming procedure to process the list inputs

Сначала я установил параметры тайм-аута select.select как в родительском, так и в родительском режимах. дочерний процесс как 0, что делает его неблокирующим. Тем не менее, вся программа будет в тупик довольно часто. Затем я попытался тщательно настроить 2 таймаута, чтобы сделать их ненулевыми. Это уменьшит частоту, с которой я сталкиваюсь с тупиком, но он все еще там.

Когда я сталкиваюсь с тупиком, мне просто нужно нажать ввод, чтобы дать новый ввод в программу, чтобы заставить программу продолжаться.

Я очень ценю, если вы сможете дать мне некоторую подсказку по этому вопросу. Спасибо, что прочитали мой вопрос.

...