0MQ: Wie ZeroMQ in einem threadsicher Art und Weise?
Lese ich die ZeroMq guide und ich stolperte auf den folgenden:
MÜSSEN Sie NICHT teilen ØMQ-sockets zwischen
threads. ØMQ Socket sind nicht
threadsicher sind. Technisch ist es möglich
um dies zu tun, aber es verlangt Semaphoren,
sperren oder Mutexe. Dadurch wird Ihr
Anwendung langsam und zerbrechlich. Der einzige
Ort, wo es aus der Ferne vernünftig
teilen sockets zwischen threads sind in
Sprache-Bindungen, die tun müssen
Magie wie die garbage collection auf
sockets.
", und später:
Denken Sie daran: nicht verwenden oder schließen von sockets, außer in dem thread, der Sie erstellt hat.
Verstand ich auch, dass die ZeroMQ Context
threadsicher ist.
Wenn eine Klasse registriert sich für ein Ereignis von einer anderen Klasse, in .Net, dieses Ereignis könnte aufgerufen werden, die von einem anderen thread als dem thread den listener erstellt wurde.
Ich denke, es gibt nur zwei Optionen, um der Lage sein, bis zum Versand etwas über ZeroMQ-Sockets innerhalb eines eventhandler:
- Synchronisieren Sie die Event-Handler-Aufruf-thread in den thread der ZeroMQ-
Socket
wurde im - Erstellen Sie eine neue ZeroMQ-
Socket
/Holen Sie sich die aktuellen ZeroMQ-Socket
für den thread innerhalb der Event-Handler mithilfe der threadsicher ZeroMQ-Context
Scheint es, dass die 0MQ-Führer entmutigt werden der erste und ich glaube nicht, dass die Schaffung einer neuen ZeroMq-Buchse für jeden thread ist performant /der Weg zu gehen.
Meine Frage:
Was ist das korrekte Muster (die Art, wie, die es sein soll) zur Veröffentlichung von Nachrichten über 0MQ aus einem Event-Handler?
Auch, haben die Autoren des Leitfadens haben die ZeroMQ-Bindung .Net im Kopf, als Sie schrieb:
Nur
Ort, wo es aus der Ferne vernünftig
teilen sockets zwischen threads sind in
Sprache-Bindungen, die tun müssen
Magie wie die garbage collection auf
sockets. ?
Hier einige samplecode zu betonen, mein problem/Frage:
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?
}
}
InformationsquelleAutor der Frage tobsen | 2011-04-30
Du musst angemeldet sein, um einen Kommentar abzugeben.
In .net framework v4 und bis können Sie die gleichzeitige Sammlung um dieses problem zu lösen. Nämlich Producer-Consumer-pattern. Mehrere threads (Handler) kann Daten senden, um eine thread-sichere queue und nur einem einzigen thread verwendet Daten aus der Warteschlange und sendet Sie mit Hilfe der socket.
Hier ist die Idee:
InformationsquelleAutor der Antwort Vadim Chekan
Können Sie erstellen, die viele von 0MQ-Steckdosen, sicherlich so viele, wie Sie haben threads. Wenn Sie eine Steckdose in einem thread, und verwenden Sie es in einem anderen, müssen Sie ausführen, ein full memory-Barriere zwischen den beiden Operationen. Alles andere führt in seltsame zufällige Fehler in libzmq, wie socket-Objekte sind nicht threadsicher.
Gibt es ein paar konventionelle Muster, obwohl ich nicht weiß, wie diese Karte speziell .NET:
InformationsquelleAutor der Antwort Pieter Hintjens
Vergessen Sie nicht, einen Blick auf die inproc-transport. Es könnte nützlich sein, um die Verwendung inproc://Anschlussbuchsen für die Inter-Thread-Kommunikation und haben ein thread geöffnet sockets zu sprechen, um andere Prozesse/Server.
Müssen Sie noch mindestens eine Steckdose pro thread, aber der inproc diejenigen, die nicht mit der IP-Netzwerk-layer an alle.
InformationsquelleAutor der Antwort Michael Dillon