Scheduling, Interrupts, Pseudointerrupts, Python-Interrupts - der Versuch einer einfachen Erklärung

Registriere dich jetzt, um exklusive Vorteile zu genießen! Als registriertes Mitglied kannst du Inhalte herunterladen und profitierst von einem werbefreien Forum.
Mach mit und werde Teil unserer Community!
  • Scheduling, Interrupts, Pseudointerrupts, Python-Interrupts - der Versuch einer einfachen Erklärung


    Motivation

    Der Begriff des Interrupts ist in den letzten Jahren sehr mehrdeutig und oft für verschiedene Zwecke verwendet worden. Die eher hardwarenahen Vertreter mögen sogar sagen: "Er wird mehr und mehr mißbraucht.". Der Artikel versucht, die verschiedenen Verwendungsformen zu erklären.


    Es verhält sich beim Begriff des "Interrupt" in etwa wie bei dem Begriff der "Batterie". Die meisten Leute werden sagen: "Meine Autobatterie war leer, weswegen ich Starthilfe benötigte.". Technisch gesehen ist das genauso falsch, wie von einem "Python Interrupt" zu sprechen, trotzdem wird jeder verstehen, was gemeint ist.


    Im Auto ist keine Batterie verbaut, sondern ein Akkumulator. Eine Batterie besteht aus zwei unterschiedlichen Materialien, die sich chemisch umwandeln und dabei Energie in Form elektrischen Stromes abgeben. Zwar ist das in erster Linie beim Akkumulator auch der Fall, allerdings ist dieser Prozeß beim Akkumulator reversibel, d.h. durch einen Stromfluß in umgekehrter Richtung können die Ausgangsmaterialien der beiden Pole chemisch wiederhergestellt werden. Bei der Batterie ist der Prozeß irreversibel. D.h. sind die beiden Ausgangsmaterialien chemisch einmal umgesetzt, so ist Schluß. Nebenbemerkung: Auf Spitzfindigkeiten wie: "Bis zur vollständigen Polarisation der Elektroden kann ich eine Batterie ebenfalls wieder aufladen und dann erhalte ich diesen marginalen Strom auch wieder zurück... ." gehe ich hier nicht ein.


    Beim "Interrupt ist das ähnlich.



    Der klassische (Hardware-) Interrupt

    Ein Interrupt ist ein Ereignis, welches ein Controller (oder eine CPU) auslöst, wenn man ihm in seinen Statusregistern mitteilt, daß er auf einen externen (Spannungsänderung egal wo) oder internen (Timer) Stimuli reagieren soll. Die Hardware des Controllers stellt für alle von ihr implementierten Interrupts eine Tabelle im Speicher bereit, welche die Adressen der Routinen enthält, welche im Falle eines Interruptereignisses auszuführen sind.

    Die Ausführung beginnt damit, daß das laufende Programm unterbrochen wird (und zwar egal, wo es sich gerade befindet) und die entsprechende Interruptroutine ausgeführt wird. Bei deren Ausführung liegt es in der Verantwortung des Programmierers:

    • die Register der CPU und ggf. andere Statusflags auf den Stack (i.d.R. dem des unterbrochenen Programmes) zu retten,
    • seine eigentliche Aktion durchzuführen (z.B. ein Zeichen aus dem Fifo eines UART zu lesen),
    • u.U. das Interruptflag des Controllers (und/oder das Interruptflag der CPU) zurückzusetzen,
    • die Register vom Stack zu restaurieren und
    • per speziellem CPU-Befehl (z.B. IRET, RETE...) wieder zum unterbrochenen Programm zurückzukehren. Dabei verhält sich der Interruptreturn-Befehl wie ein klassischer Returnbefehl mit dem Zusatz, daß er das Interruptflag der CPU zurücksetzt, um so weitere Interrupts zu erlauben.

    Nested Interrupts sind spezielle Implementierungen von Interruptroutinen. Der Programmierer sieht vor, daß seine Interruptroutine selbst wieder von einem anderen Interrupt unterbrochen werden kann, währenddessen sie noch läuft. Dabei kann es sich um einen Hardwareinterrupt höherer Priorität oder auch irgendeinen anderen Interrupt handeln. Das liegt ganz beim Programmierer der Interruptroutine. Im Unterschied zum "normalen" Interrupt gibt man bei nested Interrupts vor der Vollendung der Interruptroutine die Statusregister des Controllers und der CPU wieder frei, um möglichst schnell für neue Interrupt "empfänglich" zu sein. Die korrekte Implementierung ist dabei nicht einfach, weil ein Burst an Interrupts schnell die Stackgröße der unterbrochenen Tasks sprengen kann und auch diverse andere Probleme entstehen können...



    Eigenschaften klassischer Interrupts

    Interrupts besitzen die Eigenschaft extrem schnell (innerhalb weniger Taktzyklen der CPU) reagieren zu können und sind dadurch gekennzeichnet nur das wirklich nötigste zu tun. Klar, solange die Interruptroutine läuft, läuft sonst nichts anderes auf der den Interrupt bearbeitenden CPU.
    Timerinterrupts sind die Basis des preemptiven Schedulings eines Betriebssystems. Preemptiv bedeutet dabei, daß Prozesse/Tasks eines Betriebssystems von einem Timerinterrupt unterbrochen werden, die Interruptroutine die Register der laufenden Task auf deren Stack sichert, dann schaut, welche Task als nächstes bearbeitet werden soll, den Stackpointer der CPU auf den Stack dieser Task setzt und dann dessen gespeicherte Register restored. Diesen Vorgang nennt man "Scheduling". Der Scheduler eines (preepmtiv) geschedulten Betriebssystems tut im Kern genau das.


    Ein kurzer Ausflug zum kooperativen Scheduling. Im Prinzip verhält es sich beim kooperativen Scheduling um den gleichen Vorgang wie beim preemptiven Scheduling. Der Unterschied besteht lediglich darin, daß nicht ein Hardwaretimer zyklisch den Scheduler anstößt, sondern der Programmierer der Applikation dies über den (sog. kooperativen) Aufruf einer Betriebssystemfunktion erwirkt, um so eine andere Task die Möglichkeit zum Laufen zu ermöglichen. Ein Sleep() - Aufruf bewirkt oftmals so etwas.


    Hat man diese Art der "klassischen" Interrupts verstanden, so ist leicht ersichtlich, daß es sich hier um etwas sehr hardwarenahes handelt, auf dem ein Betriebssystemkern aufbaut. Prozesse, Threads und Tasks sind allesamt "oberhalb" dieser low-leveligen (Kernel Space) Implementierungen angesiedelt. Man spricht dann vom User-Space. Sie unterliegen i.d.R. dem Timing des Schedulers oder zumindest dem Task/Thread/Prozeß-Kontextwechsel des Schedulers, was ihre Reaktionsfähigkeit (Latenz) anbelangt. Das hat den Vorteil, daß solche Tasks i.d.R. nicht die Interruptbearbeitung des Betriebssystems korrumpieren können, allerdings auf Kosten langsamerer Reaktionszeiten.



    Python-Interrupts (Pseudointerrupts)

    Prinzipiell haben diese "Interrupts" überhaupt nichts mit den o.g. klassischen Interrupts zu tun (außer der Namensähnlichkeit). Hierbei handelt es sich um Threads im Kontext einer Python-Interpreterinstanz, welche im User Space des Betriebssystems laufen. Insofern gelten für sie die Aussagen zur Latenz ganz gewöhnlicher Threads und Prozesse. Für den Anwender wird ledigliche eine Programmierschnittstelle geschaffen, die asynchron aussieht. Das war dann aber auch schon die einzige Gemeinsamkeit mit klassischen Interrupts. Diese Art von "User-Space Interrupts" vermittelt dem Programmierer den Anschein, sporadisch beim Auftreten eines Ereignisses aufgerufen zu werden - mit allen Latenzen, die bei einem Thread und/oder Prozeßwechsel einhergehen.


    Sind Aktionen zeitunkritisch und ist das Betriebssystem nicht ausgelastet, so genügen sie sicherlich vielen Endanwendungen wie Licht ausschalten, Bewässerung stoppen... Für zeitkritische und/oder sicherheitskritische Dinge wie Notausverkettungen sind sie i.d.R. ungeeignet. Im Prinzip leidet der "Python-Interrupt" oftmals noch an anderen Limitierungen. So implementieren Pythoninterpreter u.U. selbst einen eigenen kooperativen Scheduler, der "on top" des Betriebssystemschedulers liegt und schlimmstenfalls noch nicht mal Gebrauch von mehreren CPU's macht, so sie die Hardware zur Verfügung stellt.



    Ich hoffe, mit diesem Beitrag etwas Licht in die Hintergründe der namensgleichen, jedoch sehr unterschiedlichen Bedeutungen des Begriffs "Interrupt" gebracht zu haben.



    Schöne Grüße


    schnasseldag

  • Hallo Schnasseldag,


    nur ein Wort:

    TOP!


    Beste Grüße


    Andreas

    Ich bin wirklich nicht darauf aus, Microsoft zu zerstören. Das wird nur ein völlig unbeabsichtigter Nebeneffekt sein.
    Linus Torvalds - "Vater" von Linux

    • Icon-Tutorials (IDE: Geany) - GPIO-Library - µController-Programmierung in Icon! - ser. Devices - kein Support per PM / Konversation

    Linux is like a wigwam, no windows, no gates, but with an apache inside dancing samba, very hungry eating a yacc, a gnu and a bison.