Python 通过多个推送客户端控制inproc zmq recv订单以进行推送

Python 通过多个推送客户端控制inproc zmq recv订单以进行推送,python,zeromq,Python,Zeromq,我正在使用inproc zmq套接字进行多线程数据共享。我有多个线程客户端到一个主线程;每个客户机都有一个推式插座,主机有一个拉式插座,用作所有客户机的接收器。大多数情况下,每个客户机都是独立的,但我确实有一些适度的订单要求,因为一个客户机线程相当特殊 下面是一些代码,说明了我的问题的一个变体: import threading import zmq context = zmq.Context() pull = context.socket(zmq.PULL) pull.bind('inpr

我正在使用inproc zmq套接字进行多线程数据共享。我有多个线程客户端到一个主线程;每个客户机都有一个推式插座,主机有一个拉式插座,用作所有客户机的接收器。大多数情况下,每个客户机都是独立的,但我确实有一些适度的订单要求,因为一个客户机线程相当特殊

下面是一些代码,说明了我的问题的一个变体:

import threading
import zmq

context = zmq.Context()

pull = context.socket(zmq.PULL)
pull.bind('inproc://my-socket')

def slave():
    global context
    push = context.socket(zmq.PUSH)
    push.connect('inproc://my-socket')

    for x in 'one two three'.split(' '):
        push.send('>>> '+x)
    #push.send('END')
    push.close()

def master():
    global context
    push = context.socket(zmq.PUSH)
    push.connect('inproc://my-socket')

    for x in 'one two three'.split(' '):
        push.send(x)

    x = threading.Thread(target=slave)
    x.start()

    while x.is_alive():
        pass

    push.send('END')
    push.close()

thread = threading.Thread(target=master)
thread.start()

while True:
    if pull.poll():
        x = pull.recv()
        if x == 'END':
            print 'END - exiting'
            break
        print x
从线程完全是在主线程发送了它的主有效负载之后启动的,这一事实使我认为所有的主线程数据都是在从线程数据之前启动的。然而,情况并非一贯如此。考虑下面的输出(实际上,顺序不一致,但我确实得到了这个顺序):

我希望下面的订单是可靠的,我相信这个订单是由主/从协议强制执行的

$ python zmq_threads.py 
one
two
three
>>> one
>>> two
>>> three
END - exiting

仔细想想,我发现多个套接字客户机不能保证这种同步。然而,我觉得我应该能够以某种方式刷新某些东西来强制recv的顺序(特别是使用inproc传输)。有什么想法吗?

我已经解决了这个问题,让从线程使用一个不同的套接字,该套接字在主线程中接收并发送到主程序。理论上,我认为这里可以使用拖缆设备连接inproc://my-socket-2 到inproc://my-socket,但我不认为我有任何更多的顺序保证,我只是在混音中加入另一个线程来承载拖缆

下面是我的问题代码的另一个版本,使用了所示的技巧。在所有情况下,我都觉得需要一个“结束”信标很烦人,但我不知道是否有更好的zmq/线程机制

import threading
import zmq

context = zmq.Context()

pull = context.socket(zmq.PULL)
pull.bind('inproc://my-socket')

def slave():
    global context
    push = context.socket(zmq.PUSH)
    push.connect('inproc://my-socket-2')

    for x in 'one two three'.split(' '):
        push.send('>>> '+x)
    push.send('END')
    push.close()

def master():
    global context
    push = context.socket(zmq.PUSH)
    push.connect('inproc://my-socket')

    for x in 'one two three'.split(' '):
        push.send(x)

    slaved_pull = context.socket(zmq.PULL)
    slaved_pull.bind('inproc://my-socket-2')
    x = threading.Thread(target=slave)
    x.start()

    while True:
        if slaved_pull.poll():
            x = slaved_pull.recv()
            if x == 'END':
                #print 'END - exiting'
                break
            push.send(x)

    push.send('END')
    push.close()

thread = threading.Thread(target=master)
thread.start()

while True:
    if pull.poll():
        x = pull.recv()
        if x == 'END':
            print 'END - exiting'
            break
        print x
import threading
import zmq

context = zmq.Context()

pull = context.socket(zmq.PULL)
pull.bind('inproc://my-socket')

def slave():
    global context
    push = context.socket(zmq.PUSH)
    push.connect('inproc://my-socket-2')

    for x in 'one two three'.split(' '):
        push.send('>>> '+x)
    push.send('END')
    push.close()

def master():
    global context
    push = context.socket(zmq.PUSH)
    push.connect('inproc://my-socket')

    for x in 'one two three'.split(' '):
        push.send(x)

    slaved_pull = context.socket(zmq.PULL)
    slaved_pull.bind('inproc://my-socket-2')
    x = threading.Thread(target=slave)
    x.start()

    while True:
        if slaved_pull.poll():
            x = slaved_pull.recv()
            if x == 'END':
                #print 'END - exiting'
                break
            push.send(x)

    push.send('END')
    push.close()

thread = threading.Thread(target=master)
thread.start()

while True:
    if pull.poll():
        x = pull.recv()
        if x == 'END':
            print 'END - exiting'
            break
        print x