gpt4 book ai didi

c# - 0MQ : How to use ZeroMQ in a threadsafe manner?

转载 作者:可可西里 更新时间:2023-11-01 03:05:33 26 4
gpt4 key购买 nike

我读了ZeroMq guide我偶然发现了以下内容:

You MUST NOT share ØMQ sockets between threads. ØMQ sockets are not threadsafe. Technically it's possible to do this, but it demands semaphores, locks, or mutexes. This will make your application slow and fragile. The only place where it's remotely sane to share sockets between threads are in language bindings that need to do magic like garbage collection on sockets.

及之后:

Remember: Do not use or close sockets except in the thread that created them.

我还了解到 ZeroMQ Context 是线程安全的。

如果一个类注册了另一个类的事件,在 .Net 中,此事件可能会从与创建监听器的线程不同的线程调用。

我认为只有两种选择能够通过事件处理程序中的 ZeroMQ-Sockets 进行调度:

  • 将事件处理程序调用线程同步到 ZeroMQ-Socket 中创建的线程
  • 使用线程安全的 ZeroMQ-Context 创建一个新的 ZeroMQ-Socket/为事件处理程序中的线程获取现有的 ZeroMQ-Socket

似乎 0MQ-Guide 不鼓励第一个,我不认为为每个线程创建一个新的 ZeroMq-Socket 是高性能/要走的路。

我的问题:
从事件处理程序中通过 0MQ 发布消息的正确模式(应有的方式)是什么?

此外,该指南的作者在编写时是否考虑到了适用于 .Net 的 ZeroMQ-Binding:

The only place where it's remotely sane to share sockets between threads are in language bindings that need to do magic like garbage collection on sockets. ?

这里有一些示例代码来强调我的问题/问题:

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?
}
}

最佳答案

您可以创建很多 0MQ 套接字,当然可以创建与线程一样多的套接字。如果您在一个线程中创建套接字,并在另一个线程中使用它,则必须在两个操作之间执行完整的内存屏障。其他任何事情都会导致 libzmq 中出现奇怪的随机故障,因为套接字对象不是线程安全的。

有一些常规模式,但我不知道它们如何具体映射到 .NET:

  1. 在使用它们的线程中创建套接字,期间。在紧密绑定(bind)到一个进程的线程之间共享上下文,并在非紧密绑定(bind)的线程中创建单独的内容。在高级 C API (czmq) 中,这些称为附加线程和分离线程。
  2. 在父线程中创建套接字并在线程创建时传递给附加线程。线程创建调用将执行完整的内存屏障。从此以后,在子线程中使用socket。 “使用”表示接收、发送、setsockopt、getsockopt 和关闭。
  3. 在一个线程中创建一个套接字,并在另一个线程中使用,在每次使用之间执行您自己的完整内存屏障。这是非常微妙的,如果您不知道什么是“完全内存屏障”,您不应该这样做。

关于c# - 0MQ : How to use ZeroMQ in a threadsafe manner?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5841896/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com