Многопроцессорность или многопоточность? - PullRequest
24 голосов
/ 09 апреля 2009

Я делаю программу для запуска симуляций на Python с интерфейсом wxPython. В программе вы можете создать симуляцию, и программа отображает (= рассчитывает) ее для вас. Иногда рендеринг может занимать много времени.

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

Должен ли я использовать несколько процессов или несколько потоков или что? Люди говорили мне использовать пакет multiprocessing, я проверил его, и он выглядит хорошо, но я также слышал, что процессы, в отличие от потоков, не могут делиться большим количеством информации (и я думаю, что моей программе нужно будет делиться большим информации.) Кроме того, я также слышал о Stackless Python: это отдельный вариант? Понятия не имею.

Пожалуйста, сообщите.

Ответы [ 9 ]

18 голосов
/ 09 апреля 2009

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

Это только частично верно.

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

Однако процессы обмениваются информацией через множество механизмов. Конвейер Posix (a | b) означает, что процесс a и процесс b совместно используют информацию - a записывает ее, а b читает ее. Это очень хорошо работает для многих вещей.

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

Stackless Python не связан с этим обсуждением - он быстрее и имеет другое планирование потоков. Но я не думаю, что темы - лучший путь для этого.

«Я думаю, что моей программе нужно будет поделиться большим количеством информации.»

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

«Сервер» - это другая архитектура, в которой несколько клиентских процессов получают и / или помещают информацию в центральный сервер. Это отличный способ поделиться информацией. Вы можете использовать эталонную реализацию WSGI как способ создания простого и надежного сервера.

14 голосов
/ 09 апреля 2009

В этом году был хороший разговор о многопроцессорности на Pycon. Выводом было следующее сообщение: «Используйте многопроцессорную обработку только в том случае, если вы уверены, что у вас есть проблема, которую она решит, которую нельзя решить с помощью потоков; в противном случае используйте потоки».

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

Вы можете посмотреть слайды и видео здесь: http://blip.tv/pycon-us-videos-2009-2010-2011/introduction-to-multiprocessing-in-python-1957019

http://us.pycon.org/2009/conference/schedule/event/31/

14 голосов
/ 09 апреля 2009
  • Stackless : используется 1 процессор. «Тасклеты» должны уступать добровольно. Опция вытеснения не работает постоянно.
  • С резьбой : используется 1 процессор. Собственные потоки делят время несколько случайным образом после запуска 20-100 кодов Python.
  • Многопроцессорная обработка : используется несколько процессоров

Обновление

Глубокий анализ

Используйте резьбу для легкого времени. Однако, если вы вызываете подпрограммы C, которые занимают long время перед возвратом, то это может не быть выбором, если ваша подпрограмма C не снимает блокировку.

Используйте многопроцессорность, если она очень ограничена мощностью процессора и вам нужна максимальная скорость отклика.

Не используйте без стеков, у меня раньше был segfault, и потоки в значительной степени эквивалентны, если вы не используете сотни или более.

10 голосов
/ 09 апреля 2009

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

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

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

Например, вы могли бы потенциально запустить 16 процессов на 8 двухъядерных компьютерах, но не получили бы выгоды от более чем 4 потоков на четырехъядерном компьютере. Если объем информации, которую вам нужно сообщить, невелик, многопроцессорная обработка может иметь больше смысла.

Что касается стиля youtube, который вы описали, я бы сказал, что он предполагает многопроцессорность. Если вы следуете подходам MVC, ваш GUI также не должен содержать модель (результат расчета). Благодаря многопроцессорности вы можете связаться с менеджером работ, который может сообщить, какие данные уже доступны.

5 голосов
/ 09 апреля 2009

С CPython несколько потоков не могут выполняться одновременно из-за GIL: текст ссылки .

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

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

4 голосов
/ 14 апреля 2009

Если вы хотите прочитать подробное обсуждение многопоточности в Mozilla, рассмотрите возможность обсуждения , которое началось в 2000 году. Обсуждение не обязательно отвечает на ваш вопрос. Тем не менее, это углубленное обсуждение, которое я считаю интересным и информативным, что, я полагаю, может быть весьма полезным, поскольку вы задали сложный вопрос. Надеюсь, это поможет вам принять обоснованное решение.

Кстати, некоторые участники проекта Mozilla (в частности, Брендан Эйх, технический директор Mozilla и создатель JavaScript) весьма критично относились к многопоточности, в частности. Некоторые материалы, на которые ссылаются здесь , здесь , здесь , и здесь поддерживают такой вывод.

Надеюсь, что это помогает и удачи.

1 голос
/ 13 марта 2016

Очень озадачен. Бастьен Леонар справедливо отметил, что GIL остановит любую возможность использовать многопоточность любым полезным способом. Его ссылка гласит:

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

В таком случае мультиобработка - это разумный выбор. Исходя из собственного опыта, Python + MT не приносит заметной пользы пользователю.

1 голос
/ 09 апреля 2009

Я всегда предпочитаю несколько потоков для простоты, но есть реальная проблема со сродством. Нет никакого способа (о котором я знаю) сказать, что реализация многопоточности Python связывается с конкретным процессором. Возможно, это не проблема для вас, это не так, как должно быть. Если у вас нет веских причин для этого, похоже, что ваша проблема может быть легко решена с помощью поточной реализации Python.

Если вы решили использовать обработанный, обмен информацией между подпроцессами может быть выполнен несколькими способами: соединения tcp / udp, разделяемая память или каналы. Это добавляет некоторые накладные расходы и сложность.

0 голосов
/ 09 апреля 2009

Звучит так, как будто вы хотели бы использовать потоки.

То, как вы это описали, звучало так, как будто была одна вещь, которая на самом деле требовала много ресурсов процессора ... фактического запуска симуляции.

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

То, что это НЕ даст вам, - это возможность использовать преимущества нескольких ядер / процессоров в вашей системе. Я понятия не имею, как выглядит ваша симуляция, но если она сильно загружает процессор, это может быть хорошим кандидатом для разделения. В этом случае вы можете использовать многопроцессорность для запуска отдельных частей симуляции на отдельных ядрах / процессорах. Однако это не тривиально ... теперь вам нужен какой-то способ передачи данных между процессами и обратно, в-четвертых, поскольку отдельные процессы не могут легко получить доступ к одному и тому же пространству памяти.

...