我阅读了ZeroMq 指南,偶然发现了以下内容:
您不得在线程之间共享 ØMQ 套接字。ØMQ 套接字不是线程安全的。从技术上讲,这样做是可能的,但它需要信号量、锁或互斥体。这将使您的应用程序缓慢而脆弱。在线程之间共享套接字的唯一地方是在语言绑定中需要像套接字上的垃圾收集这样的魔法。
后来:
记住:不要使用或关闭套接字,除非在创建它们的线程中。
我也明白 ZeroMQContext
是线程安全的。
如果一个类注册另一个类的事件,在 .Net 中,该事件可能会从与创建侦听器的线程不同的线程调用。
我认为只有两种选择可以通过 ZeroMQ-Sockets 从事件处理程序中分派某些东西:
- 将 eventhandler-invoking-thread 同步到 ZeroMQ-
Socket
创建的线程 - 使用线程安全的 ZeroMQ- 为事件处理程序中的线程创建一个新的 ZeroMQ-
Socket
/获取现有的 ZeroMQ-Socket
Context
似乎 0MQ-Guide 不鼓励第一个,我不认为为每个线程创建一个新的 ZeroMq-Socket 是高性能的/要走的路。
我的问题:
从事件处理程序中通过 0MQ 发布消息的正确模式(它的意思是)是什么?
此外,该指南的作者在编写时是否考虑到了 .Net 的 ZeroMQ 绑定:
在线程之间共享套接字的唯一地方是在语言绑定中需要像套接字上的垃圾收集这样的魔法。?
这是一些示例代码来强调我的问题/问题:
public class ExampleClass
{
public event EventHandler<ByteEventArgs> SomethinIsCalledFromAnotherThread;
}
public class ByteEventArgs : EventArgs
{
public byte[] BytesToSend;
}
public class Dispatcher
{
ZMQ.Context ctx;
public Dispatcher(ZMQ.Context mqcontext, ExampleClass exampleClassInstance)
{
this.ctx = mqcontext;
exampleClassInstance.SomethinIsCalledFromAnotherThread += new EventHandler<ByteEventArgs>(exampleClass_SomethinIsCalledFromAnotherThread);
}
void exampleClass_SomethinIsCalledFromAnotherThread(object sender, ByteEventArgs e)
{
// this method might be called by a different thread. So I have to get a new socket etc?
using (var socket = ctx.Socket(ZMQ.SocketType.PUSH))
{
// init socket etc..... and finally:
socket.Send(e.BytesToSend);
}
// isn't that too much overhead?
}
}