Я использую pyro для базового управления параллельными заданиями в вычислительном кластере. Я только что переехал в кластер, где буду отвечать за использование всех ядер на каждом вычислительном узле. (В предыдущих кластерах каждое ядро было отдельным узлом.) Кажется, что модуль python multiprocessing вроде как хорошо подходит для этого. Я заметил, что его также можно использовать для связи с удаленными процессами. Если кто-нибудь использовал обе платформы для взаимодействия удаленных процессов, я был бы благодарен, если бы услышал, как они сочетаются друг с другом. Очевидным преимуществом модуля многопроцессорности является то, что он встроен в версию 2.6. Кроме того, мне сложно сказать, что лучше.
Сравнение многопроцессорного модуля и пиро?
Ответы (1)
РЕДАКТИРОВАТЬ: я меняю свой ответ, чтобы вы избегали боли. многопроцессорность является незрелой, документация по BaseManager НЕПРАВИЛЬНАЯ, и если вы объектно-ориентированный мыслитель, который хочет создавать общие объекты на лету во время выполнения, ИСПОЛЬЗУЙТЕ PYRO ИЛИ ВЫ БУДЕТЕ СЕРЬЕЗНО Сожалеем об этом! Если вы просто занимаетесь функциональным программированием с использованием общей очереди, которую вы регистрируете заранее, как и все эти глупые примеры, ХОРОШО ДЛЯ ВАС.
Короткий ответ
Многопроцессорность:
- Чувствует себя неловко при выполнении объектно-ориентированных удаленных объектов
- Easy breezy crypto (ключ авторизации)
- По сети или просто межпроцессное общение
- Никаких лишних хлопот с сервером имен, как в Pyro (есть способы обойти это)
- Изменить: невозможно "зарегистрировать" объекты после создания экземпляра менеджера !! ??
- Изменить: если сервер не запущен, клиент выдает исключение «Недопустимый аргумент» вместо того, чтобы просто сказать «Не удалось подключиться» WTF !?
- Изменить: документация по BaseManager неверна! Нет способа "старт"!?!
- Изменить: очень мало примеров того, как его использовать.
Поджигатель:
- Простые удаленные объекты
- Только сетевая связь (шлейф, только если локальный)
- Изменить: эта штука просто РАБОТАЕТ, и ей нравится объектно-ориентированный обмен объектами, поэтому мне это НРАВИТСЯ.
- Изменить: Почему ЭТО не является частью стандартной библиотеки, а не той многопроцессорной чуши, которая пыталась ее скопировать и с треском провалилась?
Изменить: в первый раз, когда я ответил на этот вопрос, я только что погрузился в многопроцессорность 2.6. В коде, который я показываю ниже, класс текстуры зарегистрирован и используется в качестве прокси, однако атрибут «данные» внутри него НЕТ. Итак, угадайте, что происходит: у каждого процесса есть отдельная копия атрибута «данные» внутри прокси-сервера текстуры, несмотря на то, что вы могли ожидать. Я просто потратил неисчислимое количество часов, пытаясь выяснить, как хороший шаблон для создания общих объектов во время выполнения, и я продолжал работать с кирпичными стенами. Это было довольно запутанным и разочаровывающим. Может быть, это всего лишь я, но, глядя на скудные примеры, которые пытались использовать люди, это не похоже.
Мне нужно принять болезненное решение отказаться от библиотеки многопроцессорной обработки и отдать предпочтение Pyro, пока многопроцессорность не станет более зрелой. Вначале я был взволнован, узнав, что многопроцессорность встроена в python, но теперь я испытываю отвращение к этому и предпочитаю устанавливать пакет Pyro много-много раз, радуясь тому, что такая красивая библиотека существует для python.
Длинный ответ
Я использовал Pyro в прошлых проектах и был им очень доволен. Я также начал работать с многопроцессорной обработкой, появившейся в версии 2.6.
При многопроцессорной обработке мне было немного неудобно разрешать создание общих объектов по мере необходимости. Похоже, что в молодости многопроцессорный модуль был больше ориентирован на функциональное программирование, чем на объектно-ориентированное. Однако это не совсем так, потому что это возможно, я просто чувствую себя ограниченным вызовами "регистр".
Например:
manager.py:
from multiprocessing import Process
from multiprocessing.managers import BaseManager
class Texture(object):
def __init__(self, data):
self.data = data
def setData(self, data):
print "Calling set data %s" % (data)
self.data = data
def getData(self):
return self.data
class TextureManager(BaseManager):
def __init__(self, address=None, authkey=''):
BaseManager.__init__(self, address, authkey)
self.textures = {}
def addTexture(self, name, texture):
self.textures[name] = texture
def hasTexture(self, name):
return name in self.textures
server.py:
from multiprocessing import Process
from multiprocessing.managers import BaseManager
from manager import Texture, TextureManager
manager = TextureManager(address=('', 50000), authkey='hello')
def getTexture(name):
if manager.hasTexture(name):
return manager.textures[name]
else:
texture = Texture([0]*100)
manager.addTexture(name, texture)
manager.register(name, lambda: texture)
TextureManager.register("getTexture", getTexture)
if __name__ == "__main__":
server = manager.get_server()
server.serve_forever()
client.py:
from multiprocessing import Process
from multiprocessing.managers import BaseManager
from manager import Texture, TextureManager
if __name__ == "__main__":
manager = TextureManager(address=('127.0.0.1', 50000), authkey='hello')
manager.connect()
TextureManager.register("getTexture")
texture = manager.getTexture("texture2")
data = [2] * 100
texture.setData(data)
print "data = %s" % (texture.getData())
Неловкость, которую я описываю, исходит от server.py, где я регистрирую функцию getTexture для получения функции с определенным именем из TextureManager. Когда я буду говорить об этом, неловкость, вероятно, можно было бы устранить, если бы я сделал TextureManager разделяемым объектом, который создает / извлекает совместно используемые текстуры. Я все еще играю, но вы поняли идею. Я не помню, чтобы сталкивался с этой неловкостью при использовании пиротехники, но, вероятно, есть решение, более чистое, чем приведенный выше пример.