4

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

Для достижения этого при каждом создании задачи создается новый процесс, а для выполнения параллельного выполнения управление процессами - ThreadPoolExecutor.

import time 
from concurrent.futures import ThreadPoolExecutor 
from multiprocessing import Pipe, Process 


def task(conn, arg): 
    conn.send(arg * 2) 


def isolate_fn(fn, arg): 

    def wrapped(): 
    parent_conn, child_conn = Pipe() 
    p = Process(target=fn, args=(child_conn, arg), daemon=True) 
    try: 
     p.start() 
     r = parent_conn.recv() 
    finally: 
     p.join() 
    return r 

    return wrapped 


def main(): 
    with ThreadPoolExecutor(max_workers=4) as executor: 
    pair = [] 

    for i in range(0, 10): 
     pair.append((i, executor.submit(isolate_fn(task, i)))) 

     # This function makes the program broken. 
     # 
     print('foo') 

    time.sleep(2) 

    for arg, future in pair: 
     if future.done(): 
     print('arg: {}, res: {}'.format(arg, future.result())) 
     else: 
     print('not finished: {}'.format(arg)) 

    print('finished') 

main() 

Эта программа работает отлично, пока я не поставил функцию print('foo') внутри цикла. Если функция существует, некоторые задачи остаются незавершенными, а что хуже, сама эта программа не заканчивается.

Результаты не всегда одинаковы, но следующий типичный выход:

foo 
foo 
foo 
foo 
foo 
foo 
foo 
foo 
foo 
foo 
arg: 0, res: 0 
arg: 1, res: 2 
arg: 2, res: 4 
not finished: 3 
not finished: 4 
not finished: 5 
not finished: 6 
not finished: 7 
not finished: 8 
not finished: 9 

Почему эта программа настолько хрупким?

Я использую Python 3.4.5.

ответ

1

Попробуйте использовать

from multiprocessing import set_start_method 

... rest of your code here .... 

if __name__ == '__main__': 
    set_start_method('spawn') 
    main() 

Если вы ищете Stackoverflow для питона многопроцессорной и многопоточности вы найдете справедливое несколько вопросов, упоминая аналогичные вопросы свисающие. (особенно для версии python версии 2.7 и 3.2)

Смешивание многопоточности и многопроцессорности все еще остается проблемой, и даже документы python для multiprocessing.set_start_method упоминают об этом. В вашем случае 'spawn' и 'forkserver' должен работать без проблем.

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

КПП. «Не завершено» может по-прежнему отображаться на вашем выходе, так как вы не дожидаетесь завершения ваших подпроцессов, но весь код больше не должен висеть и всегда заканчивается чисто.

0

Вы не создаете ThreadPoolExecutor каждый раз, а используете предварительно инициализированный пул для каждой итерации. Я действительно не в состоянии отслеживать, какая заявка на печать мешает вам?

+0

Спасибо. Я уточнил функцию печати. –

 Смежные вопросы

  • Нет связанных вопросов^_^