Heim  >  Artikel  >  System-Tutorial  >  Ein genauerer Blick auf Linux-Kernel-Timer: Interrupt-basierte asynchrone Mechanismen und Nicht-Prozess-Kontextprinzipien

Ein genauerer Blick auf Linux-Kernel-Timer: Interrupt-basierte asynchrone Mechanismen und Nicht-Prozess-Kontextprinzipien

王林
王林Original
2024-07-18 11:13:55611Durchsuche

深入了解 Linux 内核定时器:基于中断的异步机制与非进程上下文原则

1. Kernel-Timer 1. Grundkonzepte

In bestimmten Szenarien müssen wir bestimmte Aktionen nach einer bestimmten Zeit ausführen und möchten keine CPU durch Warten verschwenden. Zu diesem Zeitpunkt ist der Timer ein sehr geeigneter Mechanismus. Ein Timer wird verwendet, um eine Funktion zu einem bestimmten Zeitpunkt in der Zukunft auszuführen, um eine bestimmte Aufgabe abzuschließen.

Kernel-Timer weisen den Kernel an, zu einem bestimmten Zeitpunkt eine bestimmte Funktion mit bestimmten Parametern aufzurufen. Der Timer läuft asynchron auf seinem Registranten. Wenn der Timer läuft, befindet sich die Aufgabe, die den Timer registriert hat, möglicherweise im Ruhezustand oder läuft auf anderen Prozessoren oder wurde sogar schon vor langer Zeit beendet.

Der Kernel-Timer in Linux wird basierend auf (Soft-)Interrupts Linux-Anwendungs-Timer implementiert, das heißt, er befindet sich im Interrupt-Kontext und nicht im Prozesskontext. Im Nicht-Prozess-Kontext sind einige Grundsätze zu befolgen:

Der Zugriff auf den Benutzerbereich ist nicht gestattet

Strom ist bedeutungslos und daher nicht verfügbar

Kann weder schlafen noch planen. Schedule oder eine Art wait_event können nicht aufgerufen werden, noch kann eine Funktion aufgerufen werden, die Schlaf verursachen könnte. Semaphore sind ebenfalls nicht verfügbar, da Semaphore zu einem Ruhezustand führen können.

应用定时器2_linux 应用定时器_应用定时器2安卓版下载

Der Kernel-Code kann feststellen, ob er sich derzeit im Interrupt-Kontext befindet, indem er die Funktion in_interrupt() aufruft. Solange er nicht 0 zurückgibt, bedeutet dies, dass er sich im Interrupt-Kontext befindet. Der Kernel kann durch Aufruf von in_atomic() ermitteln, ob die Planung derzeit zulässig ist. Zu den Situationen, in denen die Planung nicht zulässig ist, gehören: Sie befinden sich in einem Interrupt-Kontext und einem Kontext, der über eine Trägersperre verfügt.

Da der Timer asynchron ausgeführt wird, muss die Timer-Verarbeitungsfunktion auf den gegenseitigen Ausschlussschutz achten.

2.Vom Linux-Kernel unterstützte Timer

Der Linux-Kernel unterstützt zwei Arten von Timern:

Klassischer Timer: ein Timer, dessen Genauigkeit von der Häufigkeit der Unterbrechungen der Computeruhr abhängt. Die Timergenauigkeit ist mit einer Genauigkeit von 1000/HZms normalerweise relativ gering. Dieser Timer wird mit einer festen Frequenz generiert, also alle 1000/HZms. Wenn die Funktion „Dynamische Uhr“ nicht aktiviert ist, kann es beim Ablauf des Timers nicht zu echten Timing-Störungen kommen. Beispielsweise werden nur die folgenden Timer zum System hinzugefügt: 11-ms-, 52-ms- und 78-ms-Ablauftimer, und die Timer laufen genau ab Der Timer läuft nach einem Vielfachen von 4 ms (4, 8, 12 ...) ab, daher muss zum Zeitpunkt des Timerablaufs nicht unbedingt eine Zeitstörung vorliegen.

Timer mit hoher Bildrate: Die Präzision des klassischen Timers ist relativ gering. In einigen Situationen ist ein Timer mit höherer Präzision erforderlich, z. B. bei Multimedia-Anwendungen im chinesischen Linux-Betriebssystem. Daher wird dieser Timer-Typ in das System eingeführt. Dieser Timer kann grundsätzlich jederzeit auftreten.

应用定时器2_linux 应用定时器_应用定时器2安卓版下载

Hier braucht es auch zwei Ausnahmekonzepte:

Dynamische Uhr: Der periodische Taktgeber Linux-Anwendungstimer wird nur aktiviert, wenn eine Aufgabe tatsächlich ausgeführt werden muss, andernfalls ist die periodische Takttechnologie deaktiviert. Der Ansatz besteht darin, die periodische Uhr zu deaktivieren, wenn Sie die Ausführung im Leerlauf planen müssen; dann aktivieren Sie die periodische Uhr, bis der nächste Timer abläuft oder ein Interrupt auftritt. Eine einmalige Uhr ist eine Voraussetzung für die Realisierung einer dynamischen Uhr, da das Hauptmerkmal der dynamischen Uhr darin besteht, dass die Uhr je nach Bedarf gestoppt oder neu gestartet werden kann und eine reine periodische Uhr für diese Szenarien nicht geeignet ist.

Periodische Uhr: Eine Uhr, die die Uhrzeit periodisch bestimmt.

In Bezug auf die Anwendung haben Timer zwei Hauptverwendungszwecke:

Timeout: Zeigt eine Störung an, die nach einer bestimmten Zeitspanne auftritt. Tatsächlich wird bei Verwendung von Timeout in den meisten Fällen nicht damit gerechnet, dass das Timeout auftritt, und der Timer wird häufig vor dem Timeout abgebrochen. Darüber hinaus ist der Timeout-Vorfall oft kein genauer Vorfall, auch wenn er nicht abgebrochen wird. Beispielsweise drücken die verschiedenen im Netzwerk verwendeten Timeout-Timer häufig aus, dass dies der Fall sein kann, wenn vor diesem Zeitpunkt kein Vorfall vorliegt berücksichtigt werden ..., der Wert dieser Zeit ist oft ein Erfahrungswert oder ein berechneter Wert und stellt keinen genauen Zeitbedarf dar. In diesen Situationen reicht der klassische Timer aus.

Timer: Wird zum Implementieren des Timings verwendet. Wenn Daten zu einem bestimmten Zeitpunkt nicht an die Soundkarte gesendet werden, gelten in diesen Situationen strenge Anforderungen Mit der Zeit kommt es zu Klangverzerrungen. Zu diesem Zeitpunkt muss ein hochpräziser Timer verwendet werden.

应用定时器2安卓版下载_linux 应用定时器_应用定时器2

Linux kann durch Konfiguration dazu veranlasst werden, im folgenden Modus zu arbeiten:

Dynamischer Takt mit hoher Bildrate

Periodentakt mit hoher Bildrate

Dynamischer Takt mit niedriger Bitrate

Periodenuhr mit niedriger Coderate

3. Kernel-Timer mit niedriger Bitrate

linux 应用定时器_应用定时器2安卓版下载_应用定时器2

Der Low-Bitrate-Timer ist der gebräuchlichste Kernel-Timer. Der Kernel verwendet den Takt-Interrupt des Prozessors oder eine andere geeignete periodische Taktquelle als Zeitbasis des Timers. Taktunterbrechungen treten periodisch auf, HZ-mal pro Sekunde. Die diesem Interrupt entsprechende Timer-Verarbeitungsfunktion ist normalerweise timer_interrupt. Bei der Verarbeitung dieser Funktion wird sie schließlich an do_timer und update_process_timers angepasst. Unter anderem ist do_timer für systemweite und globale Aufgaben verantwortlich: Aktualisierung von Sekundenschnelle und Verarbeitung von Prozessstatistiken, und die letztere Funktion führt Prozessstatistiken durch, um TIMER_SOFTIRQ zu bilden, um dem Planer Zeitbewusstsein zu bieten.

Wenn der Timer abläuft, wird der Timer aus dem Aktivierungsarray entfernt, bevor die Timer-Verarbeitungsfunktion aufgerufen wird. Wenn Sie daher nach einer bestimmten Zeitspanne nach dieser Ausführung erneut ausführen möchten, müssen Sie den Timer erneut hinzufügen. Gerät. Im SMP-System wird die Timer-Funktion von der CPU ausgeführt, bei der sie registriert ist.

Die Implementierung des Kernel-Timers muss die folgenden Anforderungen und Annahmen erfüllen:

Die Timerverwaltung muss so einfach wie möglich sein.

Das Design muss eine gute Skalierbarkeit aufweisen, wenn der Aktivitätstimer stark reduziert ist

Die meisten Timer laufen innerhalb weniger Sekunden oder höchstens ein paar Minuten ab, und Timer mit langen Verzögerungen sind ziemlich selten.

Ein Timer sollte auf derselben CPU laufen, auf der er registriert wurde.

Die Implementierung des Kernel-Timers mit niedriger Bitrate ist sehr clever. Es basiert auf einer Datenstruktur pro CPU. Das Basisarray von timer_list enthält Zeiger, die auf diese Struktur zeigen. Wenn base NULL ist, wurde dieser Timer nicht zur Ausführung aufgerufen. Andernfalls gibt dieser Zeiger an, welche Datenstruktur (d. h. welche CPU) ihn ausführt.

Immer wenn der Kernel-Code einen Timer registriert (über add_timer oder mod_timer), wird die Operation letztendlich von internal_add_timer (in kernel/timer.c) ausgeführt, der den neuen Timer zur „Kaskadentabelle“ hinzufügt, die der aktuellen CPU „im Timer“ zugeordnet ist Einweg-Array.

So funktionieren kaskadierende Tabellen:

Wenn der Timer innerhalb der nächsten 0 bis 255 Augenblicke abläuft, wird er mithilfe von „expires“ zu einem der 256 Arrays hinzugefügt, die speziell für Kurzzeit-Timer vorgesehen sind (d. h., zu welchem ​​Array hinzugefügt wird, wird durch die Ablaufzeitbits bestimmt). Die unteren 8 Bits des ermittelten Bits bestimmen, zu welchem ​​Array

hinzugefügt werden soll

Wenn es in der Zukunft abläuft (aber vor 16384 Sekunden), wird es zu einem der 64 Arrays hinzugefügt. Diese 64 Arrays beziehen sich auf die 8-13 Bits des Ablaufs. Die 6 Bits bestimmen, welches Array verwendet wird .

Ähnliche Techniken werden auf die Ablaufbits 14–19, 20–25 und 26–31 angewendet.

Wenn der Timer zu einem späteren Zeitpunkt abläuft

Das obige ist der detaillierte Inhalt vonEin genauerer Blick auf Linux-Kernel-Timer: Interrupt-basierte asynchrone Mechanismen und Nicht-Prozess-Kontextprinzipien. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn