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

Schreibe einen Kommentar