【问题标题】:NetMq sockets are thread safe?NetMq 套接字是线程安全的吗?
【发布时间】:2016-05-16 16:24:42
【问题描述】:

我使用私有字段(PushSocket - zmq_push socket for netmq

private PushSocket _pushSocket;

以及在不同线程中使用此套接字的两种方法

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

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

我应该使用lock 还是其他同步原语?

【问题讨论】:

  • 您可以尝试添加 inProc 套接字并让工作线程使用它们将消息发送到 pushSocket。这样您就可以避免任何线程同步问题。

标签: c# multithreading zeromq low-latency netmq


【解决方案1】:

没有,

在理解ZeroMQ专业级建议1的基础上:
不应设计线程间共享套接字的代码。

按照设计,
ZeroMQ SF普通C通信P atterns (又名有点误导性地称为 socket(s))
不是线程安全的 (并且从未尝试过)

相信一个人以某种方式调解线程间信号的能力并不是一种信念,而是一种主要信念,即良好的可扩展并行代码应该永远不会共享,也不会阻塞

如是说ZeroMQ布道。

困惑? np.
生气的? np.
零共享零锁定 -- 尝试将其视为某种形式的碰撞避免,而不是必须从燃烧的鞭打中筛出灰烬不受控制的并发破坏。


如有疑问

最好的选择是阅读 Pieter HINTJENS 的书“Code Connected. Volume 1”,并花一些时间了解 Pieters 对可扩展代码设计原则的看法。

你很快就会爱上ZeroMQ-way的新思维方式。

【讨论】:

  • 值得注意的是Pieter Hintjens has stated that he believes this could have been the wrong choice for ZMQ - 套接字的非线程安全特性源于消息帧,而消息帧本身源于消息的寻址方式。如果该链接博客中的更改真正生效,我们可能会在某个时候拥有线程安全的套接字。但这是一场艰苦的战斗(我还没有专门调查目前的情况,那个博客是一年前的,显然消息还没有改变)。
  • 哦,是的,Jason,当然 - ZeroMQ 设计,基于这个最初的公理基石原则,可能 迟早会进化超越这一点,但是,非线程安全性原样不会降低 ZeroMQ 思维概念的能力。正如您已经确认的那样,问题是,这是否会带来任何显着好处从花费如此巨大的精力进行全面重新设计/质量检查(只是以后来被允许有时违反零共享原则的名义允许FCP-socket-endpoint在多个线程之间共享)
  • 由于当前的设计决策导致非线程安全性,我不反对 ZMQ 的能力,如果比必要的复杂一点的话。我也同意 Pieter 的观点,即提议的更改可能足以使人受益,但可能会面临足够的障碍以防止它很快发生。
【解决方案2】:

ZeroMQ 套接字不是线程安全的。我通过以下方式使用 BlockingCollection 解决了类似的问题:

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);
    }
}

您还应该实施适当的处置(中断 WorkerThread 并处置 _toSend),但仅此而已。

【讨论】:

    猜你喜欢
    • 2012-11-12
    • 1970-01-01
    • 2011-01-22
    • 1970-01-01
    • 2016-02-22
    • 2021-06-20
    • 2011-03-15
    • 2012-04-26
    • 1970-01-01
    相关资源
    最近更新 更多