Подтвердить что ты не робот

Python: когда использовать Threads или Multiprocessing

Каковы некоторые хорошие рекомендации, которые следует учитывать при принятии решения об использовании потоков или многопроцессорности, когда речь идет об эффективности и ясности кода?

4b9b3361

Ответ 1

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

Для CPython я бы использовал модуль multiprocessing в следующих случаях:

  • Мне нужно использовать несколько ядер одновременно по соображениям производительности. Глобальная блокировка интерпретатора (GIL) предотвратит любое ускорение при использовании потоков. (Иногда в любом случае вы можете уйти с потоками, например, когда основная работа выполняется в C-коде, вызванном через ctypes, или при использовании Cython и явным освобождением GIL, где он работает. Конечно, последнее требует особой осторожности.) Обратите внимание, что этот случай на самом деле довольно редок. Большинство приложений не ограничены временем процессора, и, если они действительно есть, вы обычно не используете Python.

  • Я хочу повернуть свое приложение в реальное распределенное приложение позже. Это намного проще сделать для многопроцессорного приложения.

  • Между выполняемыми задачами требуется очень мало общего состояния.

Почти во всех других случаях я бы использовал потоки. (Это включает в себя работу с графическими приложениями.)

Ответ 2

Для ясности кода, одна из самых больших вещей - научиться знать и любить Queue объект для разговора между потоками (или процессами, при использовании multiprocessing... многопроцессорность собственный объект Queue). Очереди делают вещи намного проще, и я думаю, что включить намного более чистый код.

У меня был вид для некоторых достойных примеров Queue, и у этого есть несколько отличных примеров того, как их использовать и насколько они полезны ( с той же логикой, применяемой для многопроцессорной очереди): http://effbot.org/librarybook/queue.htm

Для эффективности детали и результаты могут не заметно повлиять на большинство людей, но для python <= 3.1 реализация для CPython имеет некоторые интересные (и потенциально жестокие) проблемы эффективности многоядерных машин, которые вы можете знать об этом. Эти проблемы включают GIL. Дэвид Безли сделал видеопрезентацию на некоторое время назад, и это определенно стоит посмотреть. Подробнее здесь, в том числе последующие сообщения о значительных улучшениях на этом фронте в python 3.2.

В принципе, моя дешевая сводка многоядерной проблемы, связанной с GIL, заключается в том, что если вы ожидаете получить полное многопроцессорное использование из CPython <= 2.7 с помощью нескольких потоков, не удивляйтесь, если производительность невелика, или даже хуже, чем одноядерное. Но если ваши потоки выполняют кучу ввода/вывода (чтение/запись файлов, доступ к БД, чтение/запись сокетов и т.д.), Вы можете даже не заметить проблему.

Модуль многопроцессорности полностью устраняет эту потенциальную проблему GIL, создавая интерпретатор python (и GIL) для каждого процессора.