【发布时间】:2017-06-27 14:24:42
【问题描述】:
我阅读了ZeroMq guide 并偶然发现了以下内容:
您不得在它们之间共享 ØMQ 套接字 线程。 ØMQ 套接字不是 线程安全。技术上是可以的 做到这一点,但它需要信号量, 锁或互斥锁。这将使您的 应用程序缓慢而脆弱。唯一的 远程理智的地方 线程之间的共享套接字在 需要做的语言绑定 像垃圾收集一样的魔法 插座。
及以后:
记住:除了创建它们的线程之外,不要使用或关闭套接字。
我还了解到 ZeroMQ Context 是线程安全的。
如果一个类注册另一个类的事件,在 .Net 中,该事件可能会从与创建侦听器的线程不同的线程调用。
我认为只有两个选项可以通过 ZeroMQ-Sockets 从事件处理程序中调度某些内容:
- 将eventhandler-invoking-thread同步到ZeroMQ-
Socket创建的线程 - 使用线程安全的 ZeroMQ-
Context为事件处理程序中的线程创建一个新的 ZeroMQ-Socket/ 获取现有的 ZeroMQ-Socket
似乎 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?
}
}
【问题讨论】:
标签: c# .net multithreading thread-safety zeromq