2014-11-13 6 views
3

Я пытаюсь использовать пакет многопроцессорности в службе rpyc, но получаю ValueError: pickling is disabled, когда пытаюсь вызвать открытую функцию у клиента. Я понимаю, что пакет multiprocesing использует травление для передачи информации между процессами и что травление не допускается в rpyc, потому что это небезопасный протокол. Поэтому я не уверен, что лучший способ (или, если это так или иначе) использовать многопроцессорность с rpyc. Как я могу использовать многопроцессорность в службе rpyc? Вот на стороне сервера код:Многопроцессорный Python с RPYC «ValueError: травление отключено»

import rpyc 
from multiprocessing import Pool 

class MyService(rpyc.Service): 

    def exposed_RemotePool(self, function, arglist): 

     pool = Pool(processes = 8) 
     result = pool.map(function, arglist) 
     pool.close() 
     return result 


if __name__ == "__main__": 
    from rpyc.utils.server import ThreadedServer 
    t = ThreadedServer(MyService, port = 18861) 
    t.start() 

А вот клиент сторона код, который выдает ошибку:

import rpyc 

def square(x): 
    return x*x 

c = rpyc.connect("localhost", 18861) 
result = c.root.exposed_RemotePool(square, [1,2,3,4]) 
print(result) 
+0

http://stackoverflow.com/questions/1816958/cant-pickle-type-instancemethod-when -using-pythons-multiprocessing-pool-ma? rq = 1 –

+0

Объект обычно можно мариновать (это просто целое число), но rpyc запрещает травление и, следовательно, (по-видимому) многопроцессорную обработку, использующую травление. Я не внедряю новый протокол, я пытаюсь использовать rpyc. Если этого не сделать, я буду искать другие решения, но я бы предпочел не изобретать колесо. И если этого не может быть сделано, я затрудняюсь для того, почему существует rpyc, т. Е. Какой смысл использовать другую машину, если вы можете использовать только один процессор на этой многоядерной машине. – Michael

+0

есть много причин для многопоточности, которые нелегко сделать в сети env. одним из них является то, что назначение ЦП выполняется внутри ядра, а библиотека потоков пользователей может запрашивать только этот объект, но не всегда гарантируется. И хорошо сказано следующее: http://intermediate-and-advanced-software-carpentry.readthedocs.org/en/latest/multiprocessing.html (что GIL делает многопоточность так же быстро, как single threaded, и что «глобальная» блокировка находится внутри один хост). –

ответ

2

Вы можете включить травление в конфигурации протокола. Конфигурация хранится в виде словаря, вы можете изменить default и передать его как на сервер (protocol_config =), так и на клиента (config =). Вам также необходимо определить функцию, которая будет распараллеливаться как на стороне клиента, так и на стороне сервера. Так вот полный код server.py:

import rpyc 
from multiprocessing import Pool 
rpyc.core.protocol.DEFAULT_CONFIG['allow_pickle'] = True 

def square(x): 
    return x*x 


class MyService(rpyc.Service): 

    def exposed_RemotePool(self, function, arglist): 

     pool = Pool(processes = 8) 
     result = pool.map(function, arglist) 
     pool.close() 
     return result 



if __name__ == "__main__": 
    from rpyc.utils.server import ThreadedServer 
    t = ThreadedServer(MyService, port = 18861, protocol_config = rpyc.core.protocol.DEFAULT_CONFIG) 
    t.start() 

И client.py код:

import rpyc 

rpyc.core.protocol.DEFAULT_CONFIG['allow_pickle'] = True 

def square(x): 
    return x*x 

c = rpyc.connect("localhost", port = 18861, config = rpyc.core.protocol.DEFAULT_CONFIG) 
result = c.root.exposed_RemotePool(square, [1,2,3,4]) 
print(result) 
0

Вы должны включить его в настройках протокола. См. http://rpyc.readthedocs.org/en/latest/api/core_protocol.html#rpyc.core.protocol.DEFAULT_CONFIG

+0

С точки зрения безопасности, это хорошая идея? – Michael

+0

Я добавил 'rpyc.core.protocol.DEFAULT_CONFIG ['allow_pickle'] = True' в мой код вверху, но я все еще получаю ошибку. Не знаете, как изменить этот параметр для объекта ThreadedServer. – Michael