2013-02-15 9 views
8

Das System ist Linux (Gentoo x64), der Code ist C++. Ich habe eine Daemon-Anwendung, von der mehrere Instanzen auf demselben Rechner laufen. Die Anwendung ist selbst Multithread. Seit einiger Zeit beobachte ich merkwürdige Verzögerungen in seiner Leistung.Unabhängige Multithread-Prozesse blockieren gleichzeitig

Nachdem ich etwas Debugging-Code eingegeben hatte, kam ich mit einer seltsamen Sache, wenn mehrere Instanzen des Daemon buchstäblich gleichzeitig blockieren, die angeblich durch einen externen Grund oder etwas verursacht wird. Um das alles einfach gesagt, ich habe eine Sequenz wie folgt aus:

  1. Logzeit (t1)
  2. Sperren-Mutex
  3. Anruf C++ std::list::push_back()/pop_back() (dh sehr einfache mathematische)
  4. Unlock-Mutex
  5. Logzeit (t2)

Von Zeit zu Zeit sehe ich deutlich, dass die obige Sequenz in mehreren unabhängigen (!) Prozessen in Schritt 2 (oder wahrscheinlich in Schritt 4) für einige wirklich übermäßige Zeit in Bezug auf die Mathematik in Schritt 3 (z. B. 0,5 - 1,0 Sekunden). Als Beweis sehe ich, dass t2 in den Protokollen für alle Prozesse buchstäblich gleich ist (anders in einigen Mikrosekunden). Es sieht so aus, als ob einige Threads der Prozesse zu relativ unterschiedlichen Zeiten in den Abschnitt eintreten (ich kann deutlich 0.5 - 1 Sekunden Unterschied für t1 sehen), den Mutex sperren und zum GLEICHEN ZEITEN entsperren, nachdem er angeblich unangemessen viel Zeit damit verbracht hat das Schloss laut Protokoll (t2 - t1 Unterschied). Sieht für mich gruselig aus.

Die Manifestation des Problems ist relativ selten, etwa einmal 5-10 Minuten unter mäßiger Belastung. Im Test werden keine NTP-Zeitverschiebungen protokolliert (das war eigentlich meine erste Idee). Wenn es NTP wäre, gäbe es keine tatsächlichen Verzögerungen im Dienst, nur falsche Zeiten im Protokoll.

Wo fange ich an? Beginne ich mit der Optimierung des Schedulers? Was kann theoretisch einen gesamten Multithread-Prozess unter Linux blockieren?

+0

Also der Mutex schützt eine Ressource von den Threads geteilt .. wissen Sie, wie viele Threads vorhanden sind, wenn Sie das Blockierungsverhalten sehen? Das ist vielleicht nicht komisch, wenn eine Menge Threads in diesem Moment auf ihren Zug warten. Gibt es auch einen Grund dafür, dass der Zugriff auf die Ressource eine große zeitliche Variabilität hat? – nckturner

+3

Möglicherweise können Sie den Speicherdruck auf dem System überwachen, wenn dies geschieht. Nur eine Vermutung (nicht zu weit gestreckt) push_back könnte eine Zuweisung durchführen, die eine virtuelle Zuweisung auslösen könnte, und Langsamkeit kann auftreten, wenn die Gesamt-Commit-Gebühr bereits hoch auf dem System ist. – nanda

+0

Was ruft diese Sequenz auf? Wie oft läuft es? – ethrbunny

Antwort

1

führen Sie Ihr Programm mit:

valgrind --tool=helgrind ./your_program 

Sie werden mehr Probleme finden, die Sie erwarten.

Valgrind (Helgrind) wird Ihnen ein detailliertes Szenario Ihrer Thread-Anwendung geben, heutzutage ein Muss vor der Bereitstellung.

+0

Danke, edsiper! Valgrind ist mein heiliger Gral! Es ist jedoch nicht für das Debuggen von Produktion geeignet. – neoxic