Активизируем работу с multiprocessing в 2.7

in «Python» by Denis Mishchisin
Tags:

Размышления про multiprocessing

Важный плюс python - низкий порог вхождения в прикладные задачи - не относится к multiprocessing. В каждом мануале описано как форкать процесс, как настраивать связь между процессами и как его завершать. В некоторых - невпопад описаны низкоуровневые концепции (мьютексы, локи, соединения). Но комбинация двух факторов:

  1. Системный форк сопряжен с ненулевыми ресурсами
  2. Существующей документации хватает только для решения примитивных задач

приводит к тому, что модуль, способный обеспечить эффективное распараллеливание задач (включая распараллеливание через сеть) - используется очень редко.

Для начала ликбез:

Чем Thread отличается от Process?

Быстрый ответ: зоной ответственности за память и жизненный цикл процессов.

  • Память и жизненный цикл Thread контролируется интерпретатором python.

    Причем, в случае с python - довольно тупо контролируется. Так называемым GIL (Global Interpreter Lock). Из названия понятен принцип - только один тред одновременно читает из одного места в памяти. Это не недостаток, т.к. позволяет полностью уйти от конфликтов доступа. Кто первый встал - того и тапки, и ненадо усложнять.

  • Память и жизненный цикл Process контролируется не интерпретатором python а средствами операционной системы.

Это означает, что Thread-ы легковесны, и могут безболезненно работать с одними и теми же переменными. Но использовать преимущества многопроцессорных систем, или обеспечивать координацию потоков выполнения через сеть - зась. Process - не легковесен, ненавязчиво заманивает на поле из граблей синхронизации и сериализации данных, но позволяет эффективно использовать русурсы или (теоретически) расширяться до уровня кластера.

Когда использовать Thread а когда Process?

К multiprocessing нужно относиться как к библиотеке по управлению легковесными серверами. Парадигма "Я сейчас буду использовать только threading или только multiprocessing" - глупость. Если "это"

  • должно длительное время обрабатывать некие "транзакции"
  • имеет время жизни потенциально большее чем основной код (например пул незакрывающихся соединений с БД при работе веб сервера)

значит "это" - Process. Если "это" - много однотипных старт-стопов - значит это Thread.

Вообще, хорошо зная multiprocessing - можно полноценно отказаться от celery или tornado в 99% случаев. Любой, кто знаком с официальным маном по multiprocessing - понимает это подкоркой.