通过ØMQ发送python多处理连接

时间:2013-12-13 10:36:55

标签: python sockets multiprocessing pipe zeromq

我想通过Connection发送ØMQ个对象。有太多方面:制作人(发送Connection)和接收者(接收此Connection)。

producer.py

import zmq
import time
from multiprocessing import Pipe
from multiprocessing.reduction import reduce_connection

context = zmq.Context()
socket = context.socket(zmq.PUB)
socket.bind("tcp://*:5556")

time.sleep(1)

a, b = Pipe()
reduced_a = reduce_connection(a)
socket.send_pyobj(reduced_a)

print b.recv()

receiver.py

import zmq

context = zmq.Context()
socket = context.socket(zmq.SUB)
socket.connect ("tcp://localhost:5556")
socket.setsockopt(zmq.SUBSCRIBE, '')

obj = socket.recv_pyobj()
answer_conn = obj[0](obj[1][0],obj[1][1],obj[1][2])
# answer_conn = obj[0](*obj[1])

answer_conn.send('All is OK!')

连接反叛时:

    answer_conn = obj[0](obj[1][0],obj[1][1],obj[1][2])
  File "/usr/lib/python2.7/multiprocessing/reduction.py", line 170, in rebuild_connection
    handle = rebuild_handle(reduced_handle)
  File "/usr/lib/python2.7/multiprocessing/reduction.py", line 155, in rebuild_handle
    conn = Client(address, authkey=current_process().authkey)
  File "/usr/lib/python2.7/multiprocessing/connection.py", line 175, in Client
    answer_challenge(c, authkey)
  File "/usr/lib/python2.7/multiprocessing/connection.py", line 420, in answer_challenge
    raise AuthenticationError('digest sent was rejected')
multiprocessing.AuthenticationError: digest sent was rejected

是否有人知道可以帮助传递Connection对象的内容?

谢谢

1 个答案:

答案 0 :(得分:3)

您必须使用连接所有者的进程(生产者)authkey来重建接收器上的句柄。您可以通过ØMQ发送生产者的authkey以及pickle连接。

producer.py

import zmq
import time
from multiprocessing import Pipe, current_process
from multiprocessing.reduction import reduce_connection

context = zmq.Context()
socket = context.socket(zmq.PUB)
socket.bind("tcp://*:5556")

time.sleep(1)

a, b = Pipe()
reduced_a = reduce_connection(a)
socket.send_pyobj(reduced_a)
socket.send(current_process().authkey)

print b.recv()

receiver.py

import zmq
from multiprocessing import reduction

def rebuild_handle_with_key(pickled_data, authkey=None):
    from multiprocessing import current_process
    from multiprocessing.util import sub_debug
    from multiprocessing.connection import Client
    from multiprocessing.reduction import recv_handle
    import os
    address, handle, inherited = pickled_data
    if inherited:
        return handle
    sub_debug('rebuilding handle %d', handle)
    conn = Client(address, authkey=authkey or current_process().authkey)
    conn.send((handle, os.getpid()))
    new_handle = recv_handle(conn)
    conn.close()
    return new_handle

def rebuild_connection_with_key(reduced_handle, readable, writable, authkey=None):
    import _multiprocessing
    handle = rebuild_handle_with_key(reduced_handle, authkey)
    return _multiprocessing.Connection(
        handle, readable=readable, writable=writable
        )

reduction.rebuild_connection = rebuild_connection_with_key

context = zmq.Context()
socket = context.socket(zmq.SUB)
socket.connect ("tcp://localhost:5556")
socket.setsockopt(zmq.SUBSCRIBE, '')

obj = socket.recv_pyobj()
authkey = socket.recv()
answer_conn = obj[0](obj[1][0],obj[1][1],obj[1][2], authkey)
# answer_conn = obj[0](*obj[1])

answer_conn.send('All is OK!')

我找不到更好的方法来进行multiprocessing.reduction使用不同的authkey所以我在这里修补了它。