Какие проблемы возникнут при наивном использовании многопроцессорной обработки Python? - PullRequest
7 голосов
/ 18 декабря 2009

Мы рассматриваем возможность перефакторинга большого приложения со сложным графическим интерфейсом, который изолированным образом отделен от серверной части, чтобы использовать новый (Python 2.6) модуль многопроцессорной обработки. GUI / внутренний интерфейс использует очереди с объектами сообщений, которыми обмениваются в обоих направлениях.

Одна вещь, которую я только что заключил (предварительно, но не стесняйтесь это подтвердить), заключается в том, что «идентичность объекта» не будет сохранена в многопроцессорном интерфейсе. В настоящее время, когда наш графический пользовательский интерфейс публикует сообщение для серверной части, он ожидает получить то же сообщение обратно с результатом, присоединенным в качестве атрибута. Он использует идентификатор объекта (if received_msg is message_i_sent:) для идентификации возвращаемых сообщений в некоторых случаях ... и это, вероятно, не будет работать с многопроцессорной обработкой.

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

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

Ответы [ 3 ]

2 голосов
/ 18 декабря 2009

Я сам не использовал многопроцессорность, но представленные проблемы аналогичны опыту, который я имел в двух других областях: распределенные системы и объектные базы данных. Идентификация объекта Python может быть благословением и проклятием!

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

Для описанного конкретного случая я бы управлял идентификацией объекта на границе процесса, когда элементы находились в очереди и возвращались. При отправке задачи для обработки аннотируйте задачу с помощью id () и сохраняйте экземпляр задачи в словаре, используя в качестве ключа id (). Когда задача будет обновлена ​​/ завершена, получите точную задачу обратно по id () из словаря и примените к ней недавно обновленное состояние. Теперь точное задание и, следовательно, его личность будут сохранены.

1 голос
/ 26 декабря 2009

Вы можете попробовать пакет persistent из моего проекта GarlicSim. Это LGPL'ed.

http://github.com/cool-RR/GarlicSim/tree/development/garlicsim/garlicsim/misc/persistent/

(основной модуль в нем persistent.py)

Я часто использую это так:

# ...
self.identity = Persistent()

Тогда у меня есть идентичность, которая сохраняется во всех процессах.

1 голос
/ 18 декабря 2009

Ну, конечно же, проверка на идентичность на не-одиночном объекте (например, "a is None" или "a is False") обычно не является хорошей практикой - это может быть быстро, но действительно быстрый обход быть обменять «есть» для теста «==» и использовать инкрементный счетчик для определения личности:

# this is not threadsafe.
class Message(object):
    def _next_id():
       i = 0
       while True:
            i += 1
            yield i
    _idgen = _next_id()
    del _next_id

    def __init__(self):
        self.id = self._idgen.next()

    def __eq__(self, other):
        return (self.__class__ == other.__class__) and (self.id == other.id)

Это может быть идеей.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...