Распределенные вычисления Python (работает)
я использую старый поток для публикации нового кода, который пытается решить ту же проблему. Что представляет собой безопасный рассол? этого?
sock.py
from socket import socket
from socket import AF_INET
from socket import SOCK_STREAM
from socket import gethostbyname
from socket import gethostname
class SocketServer:
def __init__(self, port):
self.sock = socket(AF_INET, SOCK_STREAM)
self.port = port
def listen(self, data):
self.sock.bind(("127.0.0.1", self.port))
self.sock.listen(len(data))
while data:
s = self.sock.accept()[0]
siz, dat = data.pop()
s.send(siz)
s.send(dat)
s.close()
class Socket:
def __init__(self, host, port):
self.sock = socket(AF_INET, SOCK_STREAM)
self.sock.connect((host, port))
def recv(self, size):
return self.sock.recv(size)
pack.py
#http://stackoverflow.com/questions/6234586/we-need-to-pickle-any-sort-of-callable
from marshal import dumps as marshal_dumps
from pickle import dumps as pickle_dumps
from struct import pack as struct_pack
class packer:
def __init__(self):
self.f = []
def pack(self, what):
if type(what) is type(lambda:None):
self.f = []
self.f.append(marshal_dumps(what.func_code))
self.f.append(pickle_dumps(what.func_name))
self.f.append(pickle_dumps(what.func_defaults))
self.f.append(pickle_dumps(what.func_closure))
self.f = pickle_dumps(self.f)
return (struct_pack('Q', len(self.f)), self.f)
unpack.py
from types import FunctionType
from pickle import loads as pickle_loads
from marshal import loads as marshal_loads
from struct import unpack as struct_unpack
from struct import calcsize
#http://stackoverflow.com/questions/6234586/we-need-to-pickle-any-sort-of-callable
class unpacker:
def __init__(self):
self.f = []
self.fcompiled = lambda:None
self.sizeofsize = calcsize('Q')
def unpack(self, sock):
size = struct_unpack('Q', sock.recv(self.sizeofsize))[0]
self.f = pickle_loads(sock.recv(size))
a = marshal_loads(self.f[0])
b = globals() ##
c = pickle_loads(self.f[1])
d = pickle_loads(self.f[2])
e = pickle_loads(self.f[3])
self.fcompiled = FunctionType(a, b, c, d, e)
return self.fcompiled
test.py
from unpack import unpacker
from pack import packer
from sock import SocketServer
from sock import Socket
from threading import Thread
from time import sleep
count = 2
port = 4446
def f():
print 42
def server():
ss = SocketServer(port)
pack = packer()
functions = [pack.pack(f) for nothing in range(count)]
ss.listen(functions)
if __name__ == "__main__":
Thread(target=server).start()
sleep(1)
unpack = unpacker()
for nothing in range(count):
print unpack.unpack(Socket("127.0.0.1", port))
выход:
<function f at 0x12917d0>
<function f at 0x12915f0>
2 ответов
ValueError: insecure string pickle
поднимается, когда ваш рассол поврежден. Вы уверены, что получаете весь маринованный объект в одном sock.recv()
(unpack.py)?
Edit: чтобы избежать этого для любого размера, который вы могли бы сделать (ваш Socket
класс должен был бы поддерживать recv для вызова с аргументом размера буфера (i.e
class Socket:
def recv(self, bufsize):
return self.sock.recv(bufsize)
)):
import struct
struct.pack('Q', len(pickled_list))
# Send it, and then send the pickled list.
в программе приемника:
import struct
length = struct.unpack('Q', sock.recv(struct.calcsize('Q')))[0]
pickled_list = sock.recv(length)
' Q ' - это unsigned long long
. Для других структур см. модуль структуры документация
Я не думаю, что объекты процессов предназначены для отправки по сети. Посмотрите на строку 256 в multiprocessing/process.py - ...
# We subclass bytes to avoid accidental transmission of auth keys over network.
похоже, для меня есть веская причина. Если вы хотите заниматься распределенными вычислениями, возможно, вам стоит посмотреть на библиотека предназначена для этого.