• Как красиво отсортировать список в Python?

    >>> compound_transpositions = [[2, 3], [3, 4], [4, 5], [5, 6]]
    >>> coefficients = [17, 69, 84, 3, 46, 97, 12, 68, 70, 10]
    >>> compound_transpositions.sort(key=lambda x: coefficients[x[0]]-coefficients[x[1]])
    >>> compound_transpositions
    [[4, 5], [3, 4], [2, 3], [5, 6]]
    Ответ написан
    1 комментарий
  • Почему Python multiprocessing нестабилен?

    @nirvimel
    Хорошо, что вы указали в тегах Windows, это все объясняет. Под Windows нет простого способа "раздвоиться" процессу при вызове multiprocessing.Process, поэтому осуществляется очень сложная эмуляция этого поведения. При этом функция target выдирается из модуля, запускается в отдельном интерпретаторе, а все параметры сереализуются передаются и десереализуются перед вызовом target, при этом инициализация модуля в новом интерпретаторе выполняется частично (инициализируется только глобальный контекс). Подробнее об этом, например, тут, есть еще одна очень хорошая статья где подробно рассмотрен этот механизм, но сейчас не найду ссылку.

    Коротко о том, как готовить multiprocessing под Windows:
    1. Разделять процессы (вызов multiprocessing.Process()) как можно раньше в коде.
    2. По возможности избегать инициализации любых ресурсов и глобальных переменных до разделения. Учитывайте, что этот код выполняется во всех процессах независимо и может давать кучу сторонних эффектов.
    3. Не передавать через args никаких сложных объектов с "поведением" (кроме объектов из самого multiprocessing, он сам знает как их правильно передавать), только голые данные (примитивы или объекты состоящие только из примитивов), которые сериализуются без сторонних эффектов.
    4. Создавать дочерние процессы один раз, и на протяжении всего времени работать с ними посредством обмена сообщениями через Pipe/Queue. Не порождать новые процессы в цикле вычислений в момент "когда понадобятся".
    5. Queue при попытке записи/чтения может блокировать процесс, если при этом происходит запись/чтения в/из нее в другом процессе. (Думаю, именно это и происходит в коде в вопросе).
    6. Лучше использовать Pipe, который в худшем случае блокирует один процесс, а не все, как Queue.
    7. При создании процесса можно передавать ему два Pipe (input одного + output другого), в вызывающем процессе хранить соответствующие им коннекторы и только при помощи их общаться с дочерним процессом.
    8. Можно не делать process.join(), а просто читать результаты из output Pipe, они прочтутся только после того как попадут туда, что дальше будет происходить с процессом уже не важно (можно поставить return после записи в Pipe в дочернем процессе).
    Ответ написан
    4 комментария
  • Почему Python multiprocessing нестабилен?

    Olej
    @Olej
    инженер, программист, преподаватель
    3. Третий "худший"

    1. Что-то мне кажется, что в вот этом target=combinatorial_set.find_nearest_set_point - у вас должна быть критическая ошибка, которая просто убивает процессы.

    Что на размерности 30 превращается в адову кучу действий.

    2. Чего же вы при этом делаете это на Python? Вы при этом теряете раз 100 в производительности, в сравнении с языками, компилирующими в нативный код (C, C++, Go). Тем более, что там бы вы имели возможность использовать легковесные потоки взамен тяжёлых параллельных процессов.
    Ответ написан
    3 комментария
  • Локален ли GIL для каждого Python процесса?

    @radioxoma
    Да, так что можете использовать модуль multiprocessing, чтобы задействовать все ядра CPU..
    Ответ написан
    Комментировать