發送通過multiprocessing.Queue
插座正常工作的出發與python3.4,因爲從該版本ForkingPickler
is used序列化被放置在隊列中的對象和Pickler會知道如何序列插座和一個包含文件句柄的其他對象。
multiprocessing.reduction.ForkingPickler
類已經存在於python2.7中,並且可以使用pickle套接字,它只是不被multiprocessing.Queue
使用。
如果您不能切換到python3.4 +和確實需要類似的功能在python2.7一種解決方法是創建一個使用ForkingPickler序列化對象的功能,如:
from multiprocessing.reduction import ForkingPickler
import StringIO
def forking_dumps(obj):
buf = StringIO.StringIO()
ForkingPickler(buf).dump(obj)
return buf.getvalue()
相反直接發送套接字然後你需要發送它的醃製版本,並在消費者中取消它。簡單的例子:
from multiprocessing import Queue, Process
from socket import socket
import pickle
def handle(q):
sock = pickle.loads(q.get())
print 'rest:', sock.recv(2048)
if __name__ == '__main__':
sock = socket()
sock.connect(('httpbin.org', 80))
sock.send(b'GET /get\r\n')
# first bytes read in parent
print 'first part:', sock.recv(50)
q = Queue()
proc = Process(target=handle, args=(q,))
proc.start()
# use the function from above to serialize socket
q.put(forking_dumps(sock))
proc.join()
使插座與pickle纔有意義,在這裏多的背景下,這是沒有意義的將其寫入到一個文件,並在以後使用或嘗試使用它在不同的PC或原後過程已結束。因此,在全球範圍內製作插座不是一個好主意(例如通過使用copyreg
機制)。
你不能那樣做。 'Queue'旨在發送Python對象,而套接字涉及特定於OS的數據(例如套接字fd),因此它們不能簡單地傳遞給子進程。 – myaut
好吧,我找到了解決這個問題的方法。然而,即使你說這是不可能的,我真的很想看到實際做到這一點的方式。 –