Wie kommt es, dass Echtzeitbetriebssysteme als deterministisch gelten?

Auf einem PC (natürlich einem Betriebssystem) wird jedes C-Programm in Bezug auf das Timing indeterministisch. Beispielsweise dauert eine Schleife zwischen 1,2 und 1,3 Sekunden, je nachdem, "wie schnell ich ein anderes Fenster bewege". Dies liegt daran, dass das Betriebssystem Prozesse (oder Threads) dazu bringt, sich die Rechenleistung zu teilen.

Was RTOS betrifft (auf einem eingebetteten System), wenn wir eine Multithreading-Anwendung schreiben, passiert meiner Meinung nach dasselbe, je nachdem, wie viele Threads gleichzeitig ausgeführt werden.

Ich habe keine Instrumente, um dies auf einem eingebetteten System genau zu testen. Daher wollte ich fragen. Ist meine Sorge berechtigt oder übersehe ich etwas sehr Grundlegendes?

EDIT : Ich gebe ein Beispiel. wir haben task1 (dauert 10 ms) und task2 (dauert 20 ms). Sie begannen gleichzeitig mit zwei getrennten Threads. Meine Behauptung (auch Bedenken, nicht sicher) ist, dass Task1 mehr als 10 ms benötigt, weil sie die Rechenleistung mit Task2 teilen.

Der Determinismus umfasst die Menge (und das Timing) von Eingaben
Ihnen fehlt die Definition von RTOS. ;-)
Ein RTOS wird nicht verwendet, um einzelne Tasks auszuführen, die individuelle Timing-Anforderungen erfüllen müssen, es wird verwendet, um ein System auszuführen, das als Ganzes alle seine Timing-Anforderungen erfüllen muss. Deterministisch bedeutet nicht 'unabhängig von allen Umständen', sondern 'wenn ich die Umstände hinreichend gut kenne (dazu gehören definitiv höherpriore Aufgaben) kann ich eine Obergrenze vorhersagen.'

Antworten (5)

Es stimmt nicht, dass Tasks in einem RTOS automatisch deterministisch sind, aber es ist möglich, viel strengere Einschränkungen festzulegen, wann und wie oft Tasks ausgeführt werden. Ein RTOS sieht normalerweise harte Prioritäten für Aufgaben vor; zu jeder Zeit läuft die fertige Task mit der höchsten Priorität. Der Autor des Codes hat auch die vollständige Kontrolle darüber, welche Tasks ausgeführt werden; Sie können vernünftigerweise davon ausgehen, dass es keine Hintergrundaufgaben mit hoher Priorität gibt, die Ihren Code unterbrechen könnten, um beispielsweise Daten auf die Festplatte auszulagern, es sei denn, Sie haben sie geschrieben.

Darüber hinaus bieten einige Echtzeitbetriebssysteme kooperatives Multitasking. Im Gegensatz zum präventiven Multitasking wird beim kooperativen Multitasking eine Aufgabe so lange ausgeführt, bis sie freiwillig die Kontrolle über die CPU aufgibt.

Was RTOS betrifft (auf einem eingebetteten System), wenn wir eine Multithreading-Anwendung schreiben, passiert meiner Meinung nach dasselbe, je nachdem, wie viele Threads gleichzeitig ausgeführt werden.

NÖ!

Wenn das passiert, dann ist es kein REAL-TIME OS (RTOS).

Die kurze Antwort lautet, dass die Definition eines RTOS nichts mit Multitasking oder Priorität zu tun hat. Es ist einfach so, dass alle Tasks Timing-Garantien haben .

Der Rest dessen, was Sie als Merkmale eines RTOS betrachten (Priorisierung, Aufgabenerledigung usw.), sind lediglich Folgen (oder Merkmale) des Aufbaus eines Systems, bei dem Aufgaben innerhalb des angegebenen Zeitintervalls abgeschlossen werden müssen .

Multitasking in einem RTOS ist konzeptionell einfacher als in einem Softtime-Betriebssystem, da viele der komplizierten Randfälle im Wesentlichen nicht erlaubt sind.

Also, wenn Task1 10 ms und Task2 20 ms separat benötigt. Wenn sie gleichzeitig ausgeführt werden (als zwei separate Threads), wären sie dann immer noch in 10 ms bzw. 20 ms abgeschlossen?
@ozgur Nein, denn zumindest hat jeder einzelne Task-Switch Overhead, unabhängig davon, ob das Betriebssystem ein Soft-RTOS-, Hard-RTOS- oder Nicht-RTOS-Multitasker ist. Wenn Ihr System nicht über mehrere CPUs verfügt, besteht die einzige Möglichkeit, das Erscheinungsbild der gleichzeitig ausgeführten Aufgaben zu erhalten, darin, schnell zwischen ihnen umzuschalten, was den Overhead für die Aufgabenumschaltung einführt. Aus diesem Grund benötigen eine 10-ms-Aufgabe und eine 20-ms-Aufgabe, egal wie Sie sie aufteilen, immer mehr (wenn auch hoffentlich sehr wenig mehr) als 30 ms, um sie abzuschließen.
@MichaelKjörling Dein Kommentar stimmt eigentlich mit meiner Besorgnis überein. Wir können uns nie sicher sein, wann die Aufgabe abgeschlossen ist, solange die Möglichkeit besteht, dass ein anderer Thread gleichzeitig ausgeführt wird. Habe ich recht?
@ozgur Der Punkt eines RTOS ist so ziemlich der Determinismus. Wie jemand anderes betonte, steuern Sie in Echtzeitanwendungen normalerweise den gesamten ausgeführten Code selbst und können (und tun ) Maßnahmen ergreifen, um Unvorhersehbarkeiten zu vermeiden. Daher gibt es im Großen und Ganzen keinen "anderen Thread, der gleichzeitig ausgeführt werden kann", es sei denn, Sie haben diesen Code explizit selbst geschrieben.
In Anlehnung an Wikipedia: "Ein Echtzeit-Betriebssystem wird mehr dafür geschätzt, wie schnell oder vorhersehbar es reagieren kann, als für die Menge an Arbeit, die es in einem bestimmten Zeitraum ausführen kann .". en.wikipedia.org/wiki/Real-time_operating_system
Tatsächlich besteht der ganze Sinn eines RTOS darin, zu erzwingen, dass Aufgaben mit niedriger Priorität nicht gleichzeitig mit Aufgaben mit hoher Priorität ausgeführt werden.
"Die Definition eines RTOS hat nichts mit Multitasking oder Priorität zu tun" +2 dafür! Gerade in der Embedded-Welt bewirbt sich alles, was eine Art Multitasking leisten kann, als RTOS, was wirklich nicht korrekt ist.
@ pjc50 Im Allgemeinen ist das deterministische Timing für die Zuweisung oder den Zugriff auf vom Betriebssystem verwaltete Ressourcen der Punkt. Dazu gehören CPU-Zeit sowie z. B. Speicherzuweisungen oder Zugriffe auf permanente Speicher oder andere Hardwarekomponenten.
@ pjc50 - Ich denke, Ihr Kommentar ist der kritische Punkt, der vielleicht verloren geht. Die Frage enthält ein grundlegendes Missverständnis. Es gibt kein 'Task 1 gestartet und Task 2 gleichzeitig gestartet '; eine Task mit höherer Priorität (T1) wird eine Task mit niedrigerer Priorität (T2) stoppen/vorrangig machen, bis T1 beendet ist, oder sie wird von einer Task mit noch höherer Priorität (T0) vorgezogen. Natürlich kann kein Betriebssystem auf magische Weise Aufgaben ermöglichen, die mehr als die verfügbaren Ressourcen benötigen, um ihre zeitlichen, räumlichen usw. Ressourcenbeschränkungen zu erfüllen.
"Kein Betriebssystem kann auf magische Weise Aufgaben ermöglichen, die mehr als die verfügbaren Ressourcen benötigen" - Tatsächlich kann es das nicht. Aber ein echtes RTOS ermöglicht es Ihnen, im Voraus zu sagen, ob garantiert ist, dass alle Ihre Einschränkungen erfüllt werden oder nicht.
@ozgur: Sie missverstehen die Anwendungen, die auf Echtzeitbetriebssystemen ausgeführt werden. Anstatt zwei Aufgaben zu haben, die 10 ms und 20 ms dauern, haben Anwendungen auf RTOSs typischerweise Aufgaben, die jeweils 0,01 ms dauern, aber Aufgabe 1 muss ALLE 10 ms und Aufgabe 2 ALLE 20 ms ausführen. Normalerweise lassen wir in Echtzeitanwendungen nie zu, dass Threads parallel laufen, um die CPU-Leistung zu teilen. Stattdessen führen wir einen Thread so kurz wie möglich aus und lassen ihn dann schlafen. Der Punkt des RTOS ist, dass es Garantien gibt, dass, wenn ich es auffordere, mich in 10 ms aufzuwecken, es dies tut, anstatt um 10,01 ms

Ein RTOS garantiert normalerweise keinen Durchsatz , stattdessen ermöglicht es Ihnen , Latenzzeiten zu garantieren .

Dies wird normalerweise durch ein Prioritätssystem erreicht, wie hier in FreeRTOS:

Der FreeRTOS-Scheduler stellt sicher, dass Tasks im Status „Ready“ oder „Running“ immer Prozessorzeit (CPU) gegenüber Tasks mit niedrigerer Priorität, die sich ebenfalls im Status „Ready“ befinden, bevorzugt erhalten. Mit anderen Worten, die Aufgabe, die in den Zustand „Ausgeführt“ versetzt wird, ist immer die Aufgabe mit der höchsten Priorität, die ausgeführt werden kann.

Angenommen, Sie haben eine Aufgabe mit Priorität 1, die 10 ms benötigt, um ein Ereignis zu verarbeiten, eine Aufgabe mit Priorität 2, die 100 ms benötigt, um ein anderes Ereignis zu verarbeiten, und eine Aufgabe mit Priorität 3 im Hintergrund. Wenn Sie nicht mehr als jede Sekunde ein Ereignis der Priorität 1 erwarten, können Sie sagen, dass der schlimmste Fall für die Behandlung eines Ereignisses der Priorität 2 10 ms + 100 ms beträgt. Die Aufgabe mit Priorität 3 kann durch Ereignisse willkürlich verlangsamt werden, aber das ist Ihnen egal - weil sie eine niedrige Priorität hat.

Laufen in Ihrem Beispiel Aufgaben mit Priorität 1 und Aufgaben mit Priorität 2 gleichzeitig (zwei Threads wurden gleichzeitig gestartet)?
Möglicherweise ja, oder die Priorität 1 startet, während die Priorität 2 läuft. Dieses Beispiel geht von einer einzelnen CPU aus. Beachten Sie, dass die Beispielspezifikation auch die Menge der P1-Aufgabe begrenzt, die ausgeführt werden kann. Wenn Sie alle 10 ms ein P1-Ereignis erhalten und die Bearbeitung 10 ms dauert, wird niemals etwas anderes ausgeführt .
Okay, hier ist meine Frage. task1(10ms) startete gleichzeitig task2(100ms) startete. Ich glaube, Task1 braucht mehr als 10 ms, weil sie die Rechenleistung mit Task 2 teilen. Ich hoffe, ich habe mich klar ausgedrückt.
Ich denke, der Punkt ist, dass der Planer Task 1 und 2 nicht gleichzeitig ausführen wird. Task 1 (höhere Priorität) wird zuerst ausgeführt und Task 2 in die Warteschlange gestellt. 10 ms später, wenn Task 1 abgeschlossen ist, wird Task 2 ausgeführt.
Ja, die Ausführung von Task1 und Task2 wird nicht verschachtelt. Wenn eine P1-Aufgabe ausführbar ist, werden keine P2-Aufgaben geplant, bis sie abgeschlossen ist. Wenn eine P2-Aufgabe bereits ausgeführt wird, wird sie vorgezogen und angehalten, bis die gesamte P1-Arbeit abgeschlossen ist.

Ich hätte lieber einen Kommentar, aber es dauert zu viele Zeichen. Wie auch immer, ozgur, nach den Fragen in Ihren Kommentarantworten zu urteilen, scheinen Sie den Punkt zu übersehen, dass Sie nicht einfach sagen können, dass mein Thread so lange braucht, um zu laufen, und erwarten, dass er dank des Betriebssystems auf magische Weise in Verbindung mit anderen Threads funktioniert. Sie müssen Ihre Threads entwerfen und sie für die Worst-Case-Leistung analysieren. Wenn der Worst-Case Ihre Anforderungen nicht erfüllt, müssen Sie Ihre Threads neu entwerfen.

Anstatt also einfach zu sagen, dass Thread 1 10 ms und Thread 2 20 ms benötigt, müssen Sie auch sagen, dass Thread 1 alle 15 ms ausgeführt werden muss. Thread 2 muss alle 40 ms ausgeführt werden. Thread 3 muss alle 500 ms ausgeführt werden, Thread N muss alle 1500 ms ausgeführt werden. Dann weisen Sie Zeit zu, wie lange jeder Thread im schlimmsten Fall dauern kann. Sie fügen all das zusammen, identifizieren die schlimmstmöglichen Szenarien und müssen dann sicherstellen, dass jeder Thread seine Timing-Anforderungen erfüllt. Bei dieser Analyse können Sie auch feststellen, ob einige Threads eine höhere Priorität als andere haben müssen, um ihre Timing-Anforderungen zu erfüllen.

Beispielsweise wird Thread5 ausgeführt, der von Thread 4 unterbrochen wird, der von Thread 3 unterbrochen wird, der von ThreadN unterbrochen wird, was ein Worst-Case-Szenario sein könnte. Sie stellen all dies auf eine Zeitleiste und überprüfen, ob selbst in diesem Worst-Case-Szenario jeder Thread seine Timing-Anforderungen erfüllt. Sie können sicherstellen, dass die Threads dieses Worst-Case-Szenario deterministisch abschließen, indem Sie den Scheduler und die Prioritäten in einem Echtzeit-Betriebssystem verwenden. Dieser Determinismus macht ein Echtzeit-Betriebssystem aus.

Wenn Sie Threads die gleiche Priorität geben, haben Sie einen Teil (wenn nicht alles) dieses Determinismus verloren, da der Scheduler möglicherweise frei wählen kann, welchen Thread er als nächstes ausführen möchte.

In einem Betriebssystem wie Windows können Sie nicht nur nicht angeben, wann jeder Thread ausgeführt wird, Sie können nicht einmal garantieren, dass Ihre Anwendung zu einem beliebigen Zeitpunkt ausgeführt wird. Das Betriebssystem könnte Ihre Anwendung anhalten und einen Hintergrunddienst ausführen, wann immer es dies wünscht. Mit anderen Worten, es gibt keinen Determinismus. Somit ist Windows kein Echtzeitbetriebssystem. Wenn Ihre Timing-Anforderungen jedoch hoch sind, wie (Thread1 läuft alle 10 Sekunden, Thread2 läuft alle 15 Sekunden), können Sie Windows im Wesentlichen wie ein Echtzeit-Betriebssystem behandeln, solange Sie den Slop berücksichtigen und ungefähr alle 10 oder 15 Sekunden (geben oder nehmen Sie ein paar hundert Millisekunden und ein gelegentlich verpasstes Fenster) ist gut genug.

Obwohl andere Antworten angegeben haben, dass Ihr Szenario in der "realen Welt" nicht möglich ist, müssen wir ein hypothetisches System aufbauen, um Ihre Frage beantworten zu können.

Unser System besteht aus einer Kanone, die Bälle mit konstanter Geschwindigkeit abschießt, zwei Kästen, die die Bälle „fangen“ und mit jedem gefangenen Ball einen Schritt weitergehen. Die Waffe kann so umgeschaltet werden, dass sie auf eine der Kisten schießt, aber sie verliert bei jedem Umschalten eine Kugel. Die erste Box benötigt 1000 Schritte (Bälle), um ihr Ende zu erreichen, und Box 2 benötigt 2000.

Szenario 1 (Aufgaben nacheinander):
- Waffe schießt 1000 Bälle auf Box 1, wechselt (kostet 1 Kugel) und schießt 2000 Bälle auf Box 2, also insgesamt 3001 Bälle .

Szenario 2 (Aufgaben "gleichzeitig"):
- Waffe schießt 5 Bälle auf eine Box, wechselt und schießt 5 Bälle auf die andere Box, um den Anschein von Gleichzeitigkeit zu erwecken . Die Wechselkosten betragen (1000/5 x 2 =) 400 Bälle. Nach dem Schießen von 2400 Bällen erreicht Box 1 ihr Ende und Box 2 benötigt weitere 1000 Bälle, um ihr Ende zu erreichen, also insgesamt 3400 Bälle .

Wenn Sie diese Ergebnisse auf Ihr Szenario anwenden, würden Aufgabe 1 und die erste Hälfte von Aufgabe 2 nach 24 ms abgeschlossen, und die zweite Hälfte von Aufgabe 2 würde in weiteren 10 ms für insgesamt 34 ms abgeschlossen. Dies zeigt deutlich , dass die zum Erledigen der Aufgaben benötigte Zeit aufgrund des Zeitverlusts beim Wechseln zwischen den Aufgaben zunimmt . Diese Ergebnisse entsprechen auch der Ausführung von Aufgabe 1 in 12 ms und Aufgabe 2 in 22 ms.

Hochgestimmt. Diese Erklärung machte meine Frage klarer und die Antwort ist offensichtlich.