Betrachten Sie den folgenden Code:
%Vor%Auf meinem 2.6.32 System ist das Ergebnis
%Vor%Ich stimme zu, dass dies am wahrscheinlichsten ist, weil nanosleep () den Kernel auffordert, den Prozess neu zu planen. Wie kann ich das vermeiden? Ich möchte den Besitz der CPU behalten und nur für eine bestimmte Zeit herumlaufen.
Wenn Sie möchten, dass Ihre Anwendung so genau wie möglich "schlafen" kann, stellen Sie Ihre Anwendung zunächst in Echtzeitbedingungen
Schauen Sie sich Ссылка
anUnd diese andere Frage: nanosleep high cpu usage?
Der OS-Scheduler wird nichts tun wie "Oh, nimm diesen Thread für genau 86 Taktzyklen vom Prozessor und schalte ihn dann wieder ein".
Sie geben den Prozessor auf, Sie haben den Prozessor aufgegeben. Das Betriebssystem wird dich wieder anziehen, wenn es sich anfühlt. Wahrscheinlich müssen Sie warten, bis alles, was sonst noch läuft, den Prozessor verlässt, bevor Sie sich zurückschleichen können.
Nun, du wirst lernen müssen, damit zu leben, da die man-Seite zum Teil sagt: the actual time slept may be longer, due to system latencies and possible limitations in the timer resolution of the hardware
: -)
Nun zu der Antwort auf Ihre Frage, meine beste Vermutung ist, dass dies daran liegt, dass Ihre erste Schleife in Bearbeitung ist. Mit anderen Worten, es sind keine Kontextwechsel beteiligt, da Sie die CPU ganz auslasten, und Sie werden all diese Arbeit innerhalb Ihrer 100ms-Quanten tun, die Ihnen vom Scheduler gegeben werden.
Es besteht jedoch eine gute Chance, dass nanosleep
Sie ausschaltet, da Sie explizit aufgefordert werden, in den Schlafmodus zu wechseln. Es wird nicht so ineffizient sein, Ihren Prozess in eine enge while
Schleife zu bringen, bis die Dauer vorbei ist: -)
Das bedeutet, dass Sie allen Unwägbarkeiten des Schedulers unterworfen sind einschließlich die Tatsache, dass ein anderer Prozess seine Quanten völlig verbrauchen kann, daher ist Ihr Prozess möglicherweise für mindestens 100ms nicht da. Auf einem stark ausgelasteten System könnte es für eine ganze Weile aus sein.
Effizienz - Ein Os, mit dem Aufgaben mit einer Genauigkeit von einigen Taktzyklen ein- und ausgeschaltet werden konnten, würde sonst kaum etwas tun.
Es gibt spezialisierte Betriebssysteme, die das tun - aber auf normaler Hardware bezahlen Sie eine Menge Overhead für den Hypervisor
Dies ist eine haltende Antwort - ich kenne die relevanten Linux-Interna nicht, hoffentlich kann ein Experte mitkommen und es aufklären.
Eine Möglichkeit ist, dass 69us einfach der rohe Aufwand ist, um den Thread zu terminieren und neu zu planen. Obwohl der Ruhezustand kurz ist, könnte der Kernel viel Arbeit aufwenden, um einen Kontextwechsel (oder einen halben Kontextwechsel, wenn nichts zu planen ist) durchzuführen und ihn dann fast sofort rückgängig zu machen. Ich weiß nicht, wie lange Linux auf einem typischen PC "nehmen" sollte.
Wenn es das nicht erklärt, hat ein Scheduler im Allgemeinen ein Konzept eines "Timeslice", wie lange ein geplanter Thread ausgeführt wird, bevor der Scheduler darüber nachdenkt, ihn zu wechseln, es sei denn, er entplante sich selbst oder sonst etwas mit höherer Priorität wird planbar. Der Kernel wird Low-Level-Timer haben, die am Ende einer Zeitscheibe Interrupts auslösen (zusätzlich zu Interrupts, die für bestimmte andere Ereignisse wie I / O ausgelöst werden, die einen Thread entsperren könnten). Wenn ein Timeslice endet, kann der Scheduler entscheiden, ob er mit demselben Thread fortfahren oder zu einem anderen Thread wechseln möchte.
Es sieht also so aus, als wenn Sie entweder (a) den Scheduler nicht wirklich einen Timer einstellen, der Ihren Thread zur gewünschten Zeit planbar macht, er wartet nur auf eine Zeitscheibe und die CPU geht in den Leerlauf länger als nötig; oder (b) es macht Ihren Thread zum gewünschten Zeitpunkt planbar, aber wenn Sie die Ausführung durch Schlafen aufgaben, kam ein anderer Thread mit gleicher Priorität hinzu, und der Scheduler hat keinen Grund, Sie über ihn zu ziehen, bis Sie an der Reihe sind "wieder nach den Regeln, die der Scheduler normalerweise verwendet, um zu entscheiden, welcher Thread geplant werden soll.
69us ist jedoch ziemlich kurz, um ein Artefakt des Timeslicing zu sein.
Sie scheinen eine rudimentäre Lösung zu haben - Sie können für sehr kurze Zeiträume verzögern, indem Sie in einer Schleife sitzen und die Zeit überprüfen, genau wie bei einem Spinlock. Wie alle anderen sagen, können Sie in einem Nicht-Echtzeit-System mehr oder weniger per Definition nicht verlangen, dass der Scheduler Ihren Thread zu einem bestimmten Zeitpunkt ausführt. Selbst in einem Echtzeit-System können Sie verlieren, wenn Sie mit Threads gleicher Priorität konkurrieren, und wenn Sie mit Threads mit höherer Priorität konkurrieren, verlieren Sie >.