Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NetMq sockets are thread safe?

I use private field (PushSocket - zmq_push socket for netmq)

private PushSocket _pushSocket;

And two methods which use this socket in different threads

public void Method1()
{
    //.....//
    _pushSocket.SendFrame(....);
    //.....//
}

public void Method2()
{
    //.....//
    _pushSocket.SendFrame(....);
    //.....//
}

Should I use lock or another synchronization primitives?

like image 783
Evgeniy Mironov Avatar asked Oct 24 '25 00:10

Evgeniy Mironov


2 Answers

No,

on a basis of understanding the ZeroMQ professional-level recommendation No.1:
one shall not design code with sharing sockets among threads.

By design,
ZeroMQ Scalable Formal Communication Patterns ( a.k.a. a bit misleadingly nicknamed as socket(s) )
are not thread-safe ( and never tried to be ).

It is not a thing of belief in one's capabilities to somehow mediate inter-thread signalling, it is a principal belief, that good scalable parallel code shall never share, nor block.

Thus said ZeroMQ evangelism.

Confused? np.
Angry? np.
Zero-sharing, Zero-locking -- try to consider it as some form of collision avoidance, rather than having to sieve ashes from burnt thrashes of an uncontrolled concurrent havoc.


If in doubt

one has the best option, to read Pieter HINTJENS' book "Code Connected. Volume 1" and spend some time with Pieters views on scalable code design principles.

You will soon fall in love with the new style of thinking ZeroMQ-way.

like image 76
user3666197 Avatar answered Oct 26 '25 19:10

user3666197


ZeroMQ sockets are not thread safe. I've solved the similar problem by using BlockingCollection in the following way:

class MyClass 
{
    private PushSocket _pushSocket;

    private BlockingCollection<NetMQMessage> _toSend = new BlockingCollection<NetMQMessage>();

    MyClass() 
    {
        _pushSocket = new PushSocket();
        _pushSocket.Bind("someaddress");

        Task.Factory.StartNew(WorkerThread, TaskCreationOptions.LongRunning);
    }

    private void WorkerThread() 
    {
        while (true) 
        {
            NetMQMessage message = _toSend.Take();

            _pushSocket.SendMultipartMessage(message);
        }
    }

    public void Method1(NetMQMessage message) 
    {
        _toSend.Add(message);
    }

    public void Method2(NetMQMessage message) 
    {
        _toSend.Add(message);
    }
}

You should also implement the appropriate disposal (breaking WorkerThread and disposing _toSend), but this is it.

like image 41
Aleksandar Pesic Avatar answered Oct 26 '25 18:10

Aleksandar Pesic