Хобрук: Ваш путь к мастерству в программировании

Многопроцессорность Python. Взаимоблокировки очереди при установке и получении

У меня проблемы с тупиком с этим фрагментом кода:


def _entropy_split_parallel(data_train, answers_train, weights):
    CPUS = 1 #multiprocessing.cpu_count()
    NUMBER_TASKS = len(data_train[0])
    processes = []

    multi_list = zip(data_train, answers_train, weights)

    task_queue = multiprocessing.Queue()
    done_queue = multiprocessing.Queue()

    for feature_index in xrange(NUMBER_TASKS):
        task_queue.put(feature_index)

    for i in xrange(CPUS):
        process = multiprocessing.Process(target=_worker, 
                args=(multi_list, task_queue, done_queue))
        processes.append(process)
        process.start()

    min_entropy = None
    best_feature = None
    best_split = None
    for i in xrange(NUMBER_TASKS):
        entropy, feature, split = done_queue.get()
        if (entropy < min_entropy or min_entropy == None) and entropy != None:
            best_feature = feature
            best_split = split

    for i in xrange(CPUS):
        task_queue.put('STOP')

    for process in processes:
        process.join()

    return best_feature, best_split


def _worker(multi_list, task_queue, done_queue):
    feature_index = task_queue.get()
    while feature_index != 'STOP':
        result = _entropy_split3(multi_list, feature_index)
        done_queue.put(result)
        feature_index = task_queue.get()

Когда я запускаю свою программу, она отлично работает в течение нескольких прогонов через _entropy_split_parallel, но в конечном итоге блокируется. Родительский процесс блокируется done_queue.get(), а рабочий процесс блокируется done_queue.put(). Поскольку при этом очередь всегда пуста, ожидается блокировка get. Чего я не понимаю, так это почему worker блокируется на put, ведь очередь явно не заполнена (она пуста!). Я пробовал аргументы ключевого слова block и timeout, но получил тот же результат.

Я использую многопроцессорный бэкпорт, так как застрял на Python 2.5.


РЕДАКТИРОВАТЬ: Похоже, у меня также возникают проблемы с взаимоблокировкой с одним из примеров, предоставленных с модулем многопроцессорности. Это третий пример снизу здесь. Блокировка возникает, только если я вызываю Метод проверки много раз. Например, изменив нижнюю часть скрипта на это:


if __name__ == '__main__':
    freeze_support()
    for x in xrange(1000):
        test()

РЕДАКТИРОВАТЬ: я знаю, что это старый вопрос, но тестирование показывает, что это больше не проблема в Windows с Python 2.7. Я попробую Linux и отчитаюсь.


Ответы:


1

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

Во всяком случае, я столкнулся с тем же симптомом, который вы описываете, и когда я реорганизовал свою логику, чтобы главный поток не присоединялся к дочерним потокам, взаимоблокировки не было. Моя рефакторинговая логика включала в себя знание количества элементов, которые я должен получить из результатов или «готовой» очереди (которое можно предсказать на основе количества дочерних потоков или количества элементов в рабочей очереди и т. д.), и зацикливание бесконечно, пока все они не будут собраны.

«Игрушечная» иллюстрация логики:

num_items_expected = figure_it_out(work_queue, num_threads)
items_received = []
while len(items_received) < num_items_expected:
    items_received.append(done_queue.get())
    time.sleep(5)

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

26.08.2010
  • Я думаю, что все очереди должны быть пустыми, когда процессы объединяются, так что это не должно быть проблемой. Кроме того, основной процесс блокируется при размещении, а не при присоединении. Я только что обновил Python (я застрял со старой версией), поэтому я снова проверю это. 26.08.2010
  • @ajduff в моем случае взаимоблокировка произошла не при соединении, а при установке, за исключением того, что установка была в дочернем потоке. Кроме того, в моем случае очередь, в которую помещали, была пустой. Поэтому я думаю, что в вашем случае стоит попробовать (т. е. избежать присоединения главного потока к дочерним потокам). 26.08.2010

  • 2

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

    09.06.2011
    Новые материалы

    Создание кнопочного меню с использованием HTML, CSS и JavaScript
    Вы будете создавать кнопочное меню, которое имеет состояние наведения, а также позволяет вам выбирать кнопку при нажатии на нее. Финальный проект можно увидеть в этом Codepen . Шаг 1..

    Внедрите OAuth в свои веб-приложения для повышения безопасности
    OAuth — это широко распространенный стандарт авторизации, который позволяет приложениям получать доступ к ресурсам от имени пользователя, не раскрывая его пароль. Это позволяет пользователям..

    Классы в JavaScript
    class является образцом java Script Object. Конструкция «class» позволяет определять классы на основе прототипов с чистым, красивым синтаксисом. // define class Human class Human {..

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

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

    Обзор: Машинное обучение: классификация
    Только что закончил третий курс курса 4 часть специализации по машинному обучению . Как и второй курс, он был посвящен низкоуровневой работе алгоритмов машинного обучения. Что касается..

    Разработка расширений Qlik Sense с qExt
    Использование современных инструментов веб-разработки для разработки крутых расширений Вы когда-нибудь хотели кнопку для установки переменной в приложении Qlik Sense? Когда-нибудь просили..