Come mai i RTOS sono considerati deterministici?


8

Su un PC (ovviamente un sistema operativo) qualsiasi programma C diventa indeterministico in termini di tempistica. Ad esempio un ciclo impiega tra 1,2 e 1,3 secondi a seconda di "con quale velocità sto spostando un'altra finestra". È perché il sistema operativo rende i processi (o thread) condividere la potenza di elaborazione.

Per quanto riguarda gli RTOS (su un sistema incorporato), quando scriviamo un'applicazione multithreading, penso che la stessa cosa accada a seconda di quanti thread vengono eseguiti contemporaneamente.

Non ho strumenti per testarlo accuratamente su un sistema incorporato. Quindi, volevo chiedere. La mia preoccupazione è ragionevole o mi sto perdendo qualcosa di fondamentale?

EDIT : farò un esempio. abbiamo task1 (richiede 10 ms) e task2 (richiede 20 ms). Hanno iniziato contemporaneamente su due thread separati. La mia affermazione (anche preoccupante, non sono sicuro) è che task1 impiega più di 10ms, perché condividono la potenza di elaborazione con task2.


Il determinismo include l'insieme (e la tempistica) degli input
PlasmaHH,

3
Manca la definizione di RTOS. ;-)
DrFriedParts il

1
Un RTOS non viene utilizzato per eseguire singole attività che devono soddisfare i singoli requisiti di temporizzazione, ma viene utilizzato per eseguire un sistema che deve, nel suo insieme, soddisfare tutti i suoi requisiti di temporizzazione. Deterministico non significa "indipendente da tutte le circostanze", significa "quando conosco abbastanza bene le circonferenze (che include sicuramente compiti a priorità più elevata) posso prevedere un limite superiore".
Wouter van Ooijen,

Risposte:


6

Non è vero che le attività in un RTOS sono automaticamente deterministiche, ma è possibile imporre vincoli molto più stringenti su quando e quanto spesso le attività vengono eseguite. Un RTOS di solito prevede priorità concrete per le attività; in qualsiasi momento è in esecuzione l'attività pronta con la massima priorità. L'autore del codice ha anche il controllo totale su quale serie di attività sono in esecuzione; puoi ragionevolmente aspettarti che non ci siano attività in background ad alta priorità che potrebbero interrompere il tuo codice, per esempio, scambiare dati su disco, a meno che tu non li abbia scritti.

Inoltre, alcuni RTOS prevedono il multitasking cooperativo. Contrariamente al multitasking preventivo, con il multitasking cooperativo un'attività continuerà a essere eseguita fino a quando non cederà volontariamente il controllo della CPU.


10

Per quanto riguarda gli RTOS (su un sistema incorporato), quando scriviamo un'applicazione multithreading, penso che la stessa cosa accada a seconda di quanti thread vengono eseguiti contemporaneamente.

NO!

Se ciò accade, non è un sistema operativo REAL-TIME (RTOS).

La risposta breve è che la definizione di RTOS non ha nulla a che fare con il multi-tasking o la priorità. È semplicemente che tutte le attività hanno garanzie temporali .

Il resto di quelle che consideri caratteristiche di un RTOS (definizione delle priorità, completamento delle attività, ecc.) Sono semplicemente conseguenze (o caratteristiche) della costruzione di un sistema in cui le attività devono terminare entro l'intervallo di tempo specificato.

Il multi-tasking in un RTOS è concettualmente più semplice che in un sistema operativo soft-time poiché molti dei casi limite complicati non sono essenzialmente consentiti.


Pertanto, se task1 richiede 10ms e task2 richiede 20 ms separatamente. Se corressero contemporaneamente (come due thread separati) sarebbero comunque completi in 10ms e 20ms rispettivamente?
ozgur,

2
In effetti, il punto centrale di un RTOS è imporre che le attività a bassa priorità non vengano eseguite contemporaneamente alle attività ad alta priorità.
pjc50,

1
@ pjc50 - Penso che il tuo commento sia il punto critico che forse si sta perdendo. La domanda contiene un malinteso fondamentale. Non esiste "attività 1 avviata e attività 2 avviata contemporaneamente "; un'attività con priorità più alta (T1) interromperà / anticiperà un'attività con priorità inferiore (T2) fino a quando T1 non sarà terminata, oppure sarà preceduta da un'attività con priorità ancora più elevata (T0). Chiaramente, nessun sistema operativo può abilitare magicamente attività che richiedono più delle risorse disponibili per soddisfare i propri limiti di tempo, spazio, ecc.
bagliore

2
"nessun sistema operativo può abilitare magicamente attività che richiedono più delle risorse disponibili" - In effetti, non può. Ma un vero RTOS ti consentirà di dire in anticipo se è garantito o meno che tutti i tuoi vincoli saranno soddisfatti.
JimmyB,

1
@ozgur: Stai fraintendendo le applicazioni che girano su RTOS. Invece di avere due attività che richiedono 10ms e 20ms, in genere le applicazioni su RTOS hanno attività che richiedono 0,01ms ciascuna, ma l'attività 1 deve eseguire OGNI 10ms e task2 deve eseguire OGNI 20ms. Di solito nelle applicazioni in tempo reale non permettiamo mai che i thread vengano eseguiti in parallelo per condividere la potenza della CPU. Invece eseguiamo un thread per il minor tempo possibile, quindi lo lasciamo dormire. Il punto del RTOS è che ci sono garanzie che quando gli chiederò di svegliarmi in 10ms lo farà invece che a 10,01ms
slebetman

6

Un RTOS di solito non garantisce la velocità effettiva, ma consente di garantire la latenza .

Questo di solito è raggiunto da un sistema prioritario, come qui in FreeRTOS:

Lo scheduler di FreeRTOS assicura che alle attività nello stato Pronto o In esecuzione venga sempre assegnato il tempo del processore (CPU) rispetto alle attività di priorità inferiore che sono anche nello stato Pronto. In altre parole, l'attività posta nello stato In esecuzione è sempre l'attività con la priorità più alta che è in grado di eseguire.

Supponiamo di avere un'attività con priorità 1 che impiega 10 ms per gestire un evento, un'attività con priorità 2 che impiega 100 ms per gestire un evento diverso e un'attività con priorità 3 in background. Se ti aspetti di ottenere un evento prioritario 1 non più di ogni secondo, puoi dire che il caso peggiore per gestire un evento prioritario 2 è 10ms + 100ms. L'attività con priorità 3 può essere arbitrariamente rallentata dagli eventi, ma non ti interessa, perché ha una priorità bassa.


Nel tuo esempio, l'attività con priorità 1 e l'attività con priorità 2 sono in esecuzione contemporaneamente (due thread sono stati avviati contemporaneamente)?
ozgur,

1
Potenzialmente sì, oppure la priorità 1 inizia mentre la priorità 2 è in esecuzione. Questo esempio presuppone una singola CPU. Si noti che la specifica di esempio limita anche la quantità dell'attività P1 che può essere eseguita: se si ottiene un evento P1 ogni 10 ms e ci vogliono 10 ms per gestirlo, nient'altro verrà mai eseguito .
pjc50,

Ok, ecco la mia domanda. task1 (10ms) avviato contemporaneamente task2 (100ms) avviato. Credo che il task1 impieghi più di 10ms perché condividono la potenza di elaborazione con il task 2. Spero di essermi chiarito.
ozgur,

Penso che il punto in questione sia che lo scheduler non eseguirà le attività 1 e 2 contemporaneamente.
Eseguirà

1
Sì, non interleave l'esecuzione di task1 e task2. Se è possibile eseguire un'attività P1, nessuna attività P2 verrà pianificata fino al completamento. Se un'attività P2 è già in esecuzione, verrà anticipata e messa in pausa fino al completamento di tutto il lavoro P1.
pjc50,

4

Preferirei che questo fosse un commento ma ci vogliono troppi personaggi. Comunque, ozgur, a giudicare dalle domande nelle tue risposte ai commenti, sembra che manchi il punto che non puoi semplicemente dire che il mio thread impiega così tanto tempo a funzionare e si aspetta che funzioni magicamente insieme ad altri thread grazie al sistema operativo. Devi progettare i tuoi thread e analizzarli per le prestazioni peggiori. Se il caso peggiore non soddisfa i tuoi requisiti, devi riprogettare i tuoi thread.

Quindi, invece di dire semplicemente che il thread 1 richiede 10 ms per il completamento e il thread 2 richiede 20 ms, devi anche dire che il thread 1 deve essere eseguito ogni 15 ms. il thread 2 deve essere eseguito ogni 40 ms. il thread 3 deve essere eseguito ogni 500 ms, il threadN deve essere eseguito ogni 1500 ms. Quindi si assegna il tempo necessario per completare ogni thread nello scenario peggiore. Metti tutto insieme, identifichi i peggiori scenari possibili e quindi devi assicurarti che ogni thread soddisfi i suoi requisiti di tempistica. Questa analisi consente inoltre di identificare se alcuni thread devono avere una priorità più alta rispetto ad altri per soddisfare i loro requisiti di temporizzazione.

Ad esempio, il thread 5 in esecuzione viene interrotto dal thread 4 che viene interrotto dal thread 3 che viene interrotto dal thread N potrebbe essere uno scenario peggiore. Metti tutto questo su una linea temporale e verifichi che anche nel peggiore dei casi ogni thread soddisfa i suoi requisiti di temporizzazione. Puoi assicurarti che i thread completino questo scenario peggiore in modo deterministico usando lo scheduler e le priorità in un sistema operativo in tempo reale. Questo determinismo è ciò che rende un sistema operativo in tempo reale.

Se rendi i thread la stessa priorità, allora hai perso parte (se non tutto) di quel determinismo perché lo scheduler potrebbe essere libero di scegliere il thread che vuole eseguire successivamente.

In un sistema operativo come Windows, non solo non è possibile specificare quando verrà eseguito ciascun thread, ma non è nemmeno possibile garantire che l'applicazione verrà eseguita in qualsiasi momento. Il sistema operativo potrebbe arrestare l'applicazione ed eseguire alcuni servizi in background ogni volta che lo desidera. In altre parole, non c'è determinismo. Pertanto, Windows non è un sistema operativo in tempo reale. Anche se, se i tuoi requisiti di temporizzazione sono grandi, come (thread1 viene eseguito ogni 10 secondi, thread2 viene eseguito ogni 15 secondi), puoi essenzialmente trattare Windows come un sistema operativo in tempo reale purché tu tenga conto dello slop e circa ogni 10 o 15 secondi (dare o prendere alcune centinaia di millisecondi e una finestra saltata occasionale) è abbastanza buono.


1

Sebbene altre risposte abbiano affermato che nel "mondo reale" il tuo scenario non è possibile, per poter rispondere alla tua domanda, dobbiamo costruire un sistema ipotetico .

Il nostro sistema è costituito da una pistola che spara palle a una velocità costante, due scatole che "catturano" le palle e avanzano di un passo con ogni palla catturata. La pistola può essere attivata per sparare contro una delle scatole ma perde una palla ogni volta che viene cambiata. La prima casella avrà bisogno di 1000 gradini (palle) per raggiungere la sua fine e la casella 2 avrà bisogno di 2000.

Scenario 1 (compiti uno dopo l'altro):
- la pistola spara 1000 palline nella casella 1, cambia (costa 1 pallina) e lancia 2000 palline nella scatola 2, per un totale di 3001 palline .

Scenario 2 (compiti "simultanei"):
- la pistola spara 5 palline su una scatola, cambia e lancia 5 palline sull'altra scatola per dare l' apparenza di simultaneità . Il costo di commutazione è (1000/5 x 2 =) 400 palline. Quindi, dopo aver sparato 2400 palle, la casella 1 raggiungerà la sua fine e la casella 2 avrà bisogno di ulteriori 1000 palle per raggiungere la sua fine, per un totale di 3400 palle .

Applicando questi risultati allo scenario, l'attività 1 e la prima metà dell'attività 2 verrebbero completate dopo 24 ms e la seconda metà dell'attività 2 verrebbe completata in altri 10 ms per un totale di 34 ms. Ciò dimostra chiaramente che il tempo necessario per completare le attività aumenta a causa del tempo perso nel passaggio da un'attività all'altra . Questi risultati sono anche equivalenti al compito 1 che richiede 12 ms e al compito 2 che richiede 22 ms, per il completamento.


Upvoted. Questa spiegazione ha reso la mia domanda più chiara e la risposta è ovvia.
ozgur,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.