2012-04-05 2 views
3

Ich habe eine einfache Konsolenanwendung, die ZeroMQ verwendet, um Nachrichten zu senden und zu empfangen. In dem Abschnitt erhalten, ich habe die folgende Meldung Pumpe Code:.Funktioniert ZeroMQ Poll-Funktion übermäßige CPU auf .NET?

ZMQ.Context _context = new ZMQ.Context(1); 

    ZMQ.PollItem[] pollItems = new ZMQ.PollItem[0]; 

    while (!_finished) 
    { 
     if (pollItems.Length > 0) 
      context.Poll(pollItems, pollTimeout); 
     else 
      Thread.Sleep(1); 

     if (_receiversChanged) 
      UpdatePollItems(ref pollItems); 
    } 

(Die Idee ist, dass ich hinzufügen und Elemente aus dem Anfragenden zur Laufzeit entfernen können, wie ich Empfänger hinzufügen müssen UpdatePollItems einfach erstellt ein neues Array, wenn sich der Empfängersatz ändert.)

Ich habe pollTimeout-Werte von 50ms und 500ms probiert, aber die App (die auf ihrem Hauptthread auf Console.ReadKey sitzt) verwendet immer noch 100% eines Kerns, auch wenn nicht Nachrichten werden gesendet. Ich führte die App unter dem Profiler und bestätigte, dass es ZMQ.Context.Poller ist, der die ganze CPU kaut.

Haben andere ähnliches Verhalten gesehen? Ich verwende die neueste ZeroMQ C# -Bindung (clrzmq-x64.2.2.3 von NuGet).

+0

Poll() verwendet wahrscheinlich busy wait, was unvermeidlich ist, wenn Sie eine niedrige Latenzzeit wünschen. – bongi

+0

http://lists.zeromq.org/pipermail/zeromq-dev/2012-February/015734.html schlägt vor, dass mit der Java-Bindung CPU-Auslastung sollte ziemlich viel 0 sein. Es wäre eine Schande, wenn die .NET-Implementierung wasn wäre 't as good ... – SteveWilkinson

Antwort

4

Ja, es ist ein Fehler im Treiber. Ich habe das auch getroffen. Mit Blick auf den Code ist es möglich, dass die .net 4-Version besser laufen sollte, aber Sie müssen es neu kompilieren. Ich werde prüfen, ob der umgeschriebene Code als Pull-Request reintegriert werden könnte.

+0

Danke Matthias - Ich würde mich freuen zu hören, wenn Sie eine Lösung haben. Thread.Sleep zur Rettung vorerst ... – SteveWilkinson

4

Ich werde das erraten, wenn Sie sagen, Sie die Umfrage-Timeout auf 500 ms einstellen, dass Sie die Variable PollTimeout bis 500 setzen die nicht korrekt wäre. Bei einem Timeout von 500 ms sollte die variable PollTimeout auf 500000. gesetzt Wenn Sie das tun context.Poll (..., 500) ist als 500 & mgr; s interpretiert und es wird abgerundet intern auf 0 ms aus.

Ich überprüfte auf mein eigenes System, das 500 vorbei CPU-Auslastung zwischen 90 und 100% abfragt verursacht. Wenn Sie den Wert auf etwas über 1000 setzen, wird die CPU-Nutzung viel geringer und für 500000 (500ms) sollte sie vernachlässigbar sein.

So oder so, geben Sie bitte Ihre Codebeispiel auf die Initialisierung der Variablen PollTimeout aktualisieren. Wenn ich komplett außerhalb der Basis bin, dann wird es zumindest andere Möchtegern-Beantworter davon abhalten, diesen Weg einzuschlagen.