0
votes

The ZeroMQ guide states that sockets shouldn't be shared between threads. However, in the Pyre ZeroMQ project, at some point in the zhelper module a socket is created in a thread then used in a new thread :

def zthread_fork(ctx, func, *args, **kwargs):
    """
    Create an attached thread. An attached thread gets a ctx and a PAIR
    pipe back to its parent. It must monitor its pipe, and exit if the
    pipe becomes unreadable. Returns pipe, or NULL if there was an error.
    """
    a = ctx.socket(zmq.PAIR)
    a.linger = 0
    b = ctx.socket(zmq.PAIR)
    b.linger = 0
    a.set_hwm(1)
    b.set_hwm(1)
    iface = "inproc://%s" % binascii.hexlify(os.urandom(8))
    a.bind(iface)
    b.connect(iface)

    thread = threading.Thread(target=func, args=((ctx, b)+args), kwargs=kwargs)
    #thread.daemon = True
    thread.start()

    return a

Is it okay to create a ZeroMQ socket in a thread and then use it in another thread if the creator thread doesn't actually call any socket functions ?

1
It can cause locks/issues if shared across threads yes. But technically it's possible. I would advice against it but if you have your head where it should be it's possible to make it work.Torxed
Just out of curiosity, what holds you from creating the socket in the new thread?Turion
Nothing, and it is what I do in my own code. However, this example is a sample from an official ZeroMQ project. That is why I'm a bit confused here as it doesn't seem as it follows the usual recommendations.Charles

1 Answers

1
votes

You can pass a socket to another thread when you put a memory barrier between. Locks and other synchronisation primitives use memory barriers, so yeah, you can use any synchronisation primitives to just wrap your socket.

What I would, however, like to point out is that having to wrap a socket in a mutex usually says that something is wrong with your architecture. What you should do is to set up multiple inproc sockets, each thread owning one or more sockets, and have the threads talk to each other via these inproc sockets rather than exchanging sockets using mutexes.