Operazione: Descrizione dell'architettura Run-time |
|
 |
Questa attività definisce l'architettura di un processo per il sistema in termini di classi attive e delle relative istanze e la loro relazione con i thread e processi del sistema operativo. |
|
Scopo
-
Per analizzare i requisiti concorrenza,
-
Per identificare i processi e i relativi cicli di vita
-
Per identificare i meccanismi di comunicazione interni al processo e allocare le risorse di coordinamento
interne al processo
-
Per distribuire gli elementi modello tra i processi.
|
Relazioni
Ruoli | Principale:
| Aggiuntivo:
| Assistenza:
|
Input | Obbligatorio:
| Facoltativo:
| Esterno:
|
Output |
|
Descrizione principale
Gli oggetti attivi (cioè, le istanze delle classi attive) sono utilizzati per rappresentare i thread di esecuzione
simultanei nel sistema: in modo teorico, ciascun oggetto attivo ha il proprio thread di controllo e, convenzionalmente,
è la radice principale di un frame dello stack di esecuzione. L'associazione degli oggetti attivi agli effettivi thread
o processi del sistema operativo può variare a seconda dei requisiti di risposta e sarà influenzata da valutazioni
sull'eccesso dei passaggi di contesto. Ad esempio, è possibile per un numero di oggetti attivi, in combinazione con un
semplice programma di pianificazione, condividere un singolo thread del sistema operativo, mostrando pertanto di avere
un'esecuzione simultanea. Tuttavia, se uno qualsiasi degli oggetti attivi evidenzia sintomi di blocco, ad esempio
eseguendo operazioni di input-output sincrone, gli altri oggetti attivi nel gruppo non saranno in grado di rispondere
agli eventi che si verificheranno mentre il thread del sistema operativo è bloccato.
D'altro canto, fornendo a ciascun oggetto attivo il proprio thread di sistema operativo può determinare una più rapida
risposta, a patto che le risorse di elaborazione non siano contrariamente influenzate dall'ulteriore eccesso di
passaggi di contesto.
Nei sistemi in tempo reale, le capsule descritte nella sezione Prodotto di
lavoro: Capsule sono il modo consigliato per modellare la simultaneità; come per le classi attive, ciascuna capsula
ha il proprio thread di controllo notazionale, ma le capsule hanno ulteriori semantiche di composizione e di
incapsulamento per rendere la modellazione di complessi problemi in tempo reale più trattabile.
Questa attività definisce l'architettura di un processo per il sistema in termini di classi attive e delle relative
istanze e la loro relazione con i thread e processi del sistema operativo. Allo stesso modo, per sistemi in tempo
reale, l'architettura del processo sarà definita in termini di capsule e di una mappatura associata di queste ai
processi e thread del sistema operativo.
Nella fase iniziale di elaborazione, questa architettura sarà alquanto preliminare, ma nella fase finale i processi e
thread dovrebbero essere ben definiti. I risultati di questa attività vengono catturati nel modello di progettazione -
in particolare, nella vista processi (consultare la sezione Concetto: Vista
processi).
|
Passi
Analisi dei requisiti di simultaneità
Scopo
|
Per definire l'ambito in cui è richiesta l'esecuzione parallela per il sistema. Questa definizione sarà
di guida per strutturare l'architettura.
|
Durante l' Task: Identificazione degli elementi di progettazione, sono stati
considerati i requisiti di simultaneità gestiti principalmente dalle domande effettuate spontaneamente per la
concorrenza nel dominio del problema.
Il risultato conseguente è stato un'insieme di classi attive, che rappresentano i thread logici di controllo nel
sistema. Nei sistemi in tempo reale, queste classi attive sono rappresentate da Prodotto di lavoro: Capsula.
In questa fase, vengono considerate altre fonti dei requisiti di concorrenza - quelle previste dai requisiti non
funzionali del sistema.
I requisiti di concorrenza sono gestiti da:
-
Il livello in cui deve essere distribuito il sistema. Un sistema il cui funzionamento deve essere
distribuito su processori o nodi richiede virtualmente un'architettura a più processi. Un sistema che utilizza
qualche tipo di sistema di gestione del database o gestore delle transazioni deve anche tenere conto dei processi
che tali sottosistemi principali forniscono.
-
La rapidità di calcolo degli algoritmi chiave. Per poter fornire degli ottimi tempi di risposta, potrebbe
essere necessario assegnare delle intense attività di calcolo ad un processo o thread in modo che il sistema possa
essere ancora in grado di rispondere agli input dell'utente mentre viene eseguito il calcolo, sebbene con poche
risorse.
-
Il livello di esecuzione parallela supportata dall'ambiente. Se il sistema operativo o ambiente non supporta
i thread (processi leggeri), è di scarsa importanza considerarne il loro impatto sull'architettura del sistema.
-
La necessità della funzione di tolleranza dell'errore nel sistema. I processori di backup richiedono un
processo di copia e la necessità di avere i processi primari e di backup sincronizzati.
-
Il modello di arrivo degli eventi nel sistema. In sistemi con unità esterne o sensori, i modelli di arrivo
di eventi in entrata possono differire da sensore a sensore. Alcuni eventi possono essere periodici (ad esempio
verificarsi durante un intervallo prefissato, con più o meno un tempo minimo) oppure aperiodici (ad esempio con un
intervallo irregolare). Le classi attive che rappresentano le unità che generano diversi modelli di eventi saranno
di solito assegnate a diversi thread del sistema operativo, con differenti algoritmi di pianificazione, per essere
certi di non mancare gli eventi o le scadenze di elaborazione (nel caso questo sia un requisito del sistema). Tale
ragionamento si applica in modo uguale alle capsule, quando utilizzate nella progettazione dei sistemi in tempo
reale.
Così come per molti problemi strutturali, questi requisiti possono essere alquanto esclusivi in modo reciproco. E'
probabile che si abbia, almeno inizialmente, dei requisiti in conflitto. La classificazione dei requisiti in termini di
importanza faciliteranno l'utente nella risoluzione del conflitto.
|
Identificazione dei processi e thread
Scopo
|
Per definire i processi ed i thread che saranno presenti nel sistema.
|
L'approccio più semplice è di allocare tutti gli oggetti attivi in un thread o processo comune e di utilizzare un
semplice programma di pianificazione degli oggetti attivi, poiché ciò riduce l'eccesso di passaggio di contesto.
Tuttavia, in alcuni casi, potrebbe essere necessario distribuire gli oggetti attivi su uno o più thread o processi. Ciò
sarà quasi certamente il caso della maggior parte dei sistemi in tempo reale, dove le capsule utilizzate per
rappresentare i thread logici in alcuni casi devono soddisfare rigidi requisiti di pianificazione.
Se un oggetto attivo che condivide un thread del sistema operativo con altri oggetti attivi esegue una chiamata
sincrona ad un altro processo o thread e ciò blocca il thread del sistema operativo condiviso dell'oggetto che viene
richiamato, tale operazione sospenderà automaticamente tutti gli altri oggetti attivi presenti nel processo richiamato.
Ora, ciò non deve il caso in questione: una chiamata sincrona dal punto di vista dell'oggetto attivo potrebbe essere
gestita in modo asincrona da parte del programma di pianificazione che controlla il gruppo di oggetti attivi - il
programma di pianificazione sospende l'oggetto attivo che esegue la chiamata (attendendo la conclusione della chiamata
sincrona) e quindi pianifica l'esecuzione di altri oggetti attivi.
Quando l'operazione 'sincrona' originale viene completata, è possibile ripristinare l'oggetto attivo che viene
richiamato. Tuttavia, questo approccio potrebbe non essere sempre possibile, poiché il programma di pianificazione
potrebbe non essere realizzato per intercettare tutte le chiamate sincrone prima che vengano bloccate. Da notare che
una chiamata sincrona tra oggetti attivi che utilizzano lo stesso processo o thread del sistema operativo può essere
gestita, per generalità, in questo modo dal programma di pianificazione - ed è equivalente in realtà a una chiamata di
procedura dal punto di vista dell'oggetto attivo che si sta richiamando.
Ciò conduce alla conclusione che gli oggetti attivi devono essere raggruppati in processi o thread in base alle
rispettive esigenze di essere eseguiti simultaneamente con chiamate sincrone che bloccano il thread. Vale a dire,
l'unica eccezione in cui un oggetto attivo deve essere integrato nello stesso processo o thread con un altro oggetto
che utilizza chiamate sincrone che bloccano il thread è quando non ha necessità di essere processato simultaneamente
con quell'oggetto e può tollerare di non essere eseguito mentre l'altro oggetto è bloccato. Nel caso estremo, quando la
velocità di risposta è determinante, potrebbe risultare necessario un thread o processo separato per ogni oggetto
attivo.
Nei sistemi in tempo reale, l'utilizzo di interfacce basate su messaggi delle capsule significa che è più facile
elaborare un programma di pianificazione che garantisca, almeno per comunicazioni capsula a capsula, l'operatività
ininterrotta dei thread del sistema operativo supportato, anche quando una capsula comunica in modo sincrono con
un'altra capsula. Tuttavia, è ancora possibile per una capsula emettere una richiesta direttamente al sistema
operativo, ad esempio, per un'attesa programmata sincrona, che bloccherebbe il thread. E' necessario stabilire delle
convenzioni, per i servizi di livello inferiore richiamati dalle capsule, che evitano questo comportamento, nel caso le
capsule debbano condividere un thread comune (e utilizzare un semplice programma di pianificazione per simulare la
simultaneità).
Come regola generale, nelle situazioni sopra riportate è preferibile utilizzare processi leggeri anziché processi
complessi poiché determinano un minore sovraccarico. Tuttavia, resta l'obbiettivo di sfruttare alcune delle speciali
caratteristiche dei processi in determinati casi essenziali. Poiché i thread condividono la stessa area di
indirizzamento, essi sono inerentemente più rischiosi dei processi. Se la possibilità di una sovrascrittura accidentale
non è tollerabile, è preferibile utilizzare i processi. Inoltre, poiché i processi rappresentano unità indipendenti di
ripristino nella maggior parte dei sistemi operativi, potrebbe essere utile assegnare gli oggetti attivi ai processi in
base alle rispettive necessità di essere ripristinati in modo indipendente. In conclusione, tutti gli oggetti attivi
che devono essere ripristinati come un'unità possono essere integrati insieme nello stesso processo.
Per ciascun flusso separato del controllo richiesto dal sistema, creare un processo o thread (processo lightweight). Si
consiglia l'utilizzo di un thread nei casi in cui è richiesto un flusso del controllo nidificato (ad esempio, se
all'interno di un processo occorre un flusso indipendente del controllo a livello di attività secondaria).
Ad esempio, si potrebbero utilizzare thread separati del controllo per:
-
Suddividere le problematiche tra diverse aree del software
-
Sfruttare più CPU in un nodo o in più nodi di un sistema distribuito
-
Aumentare l'utilizzo della CPU mediante allocazione dei cicli ad altre attività quando viene sospeso un thread del
controllo
-
Dare una priorità alle attività
-
Supportare la condivisione del carico su diversi processi e processori
-
Raggiungere una più elevata disponibilità del sistema mediante processi di backup
-
Supportare il DBMS, il Transaction Manager o altri principali sottosistemi.
Esempio
Nello sportello automatico ATM (Automated Teller Machine) gli eventi asincroni devono essere gestiti da tre diversi
sorgenti: l'utente del sistema, i dispositivi ATM (nel caso di un blocco del distributore banconote, ad esempio) o la
rete ATM (nel caso di una direttiva di chiusura dalla rete). Per gestire questi eventi asincroni, è possibile definire
tre diversi thread di esecuzione all'interno dell'ATM stesso, come mostrato di seguito utilizzando le classi attive in
UML.
Processi e thread all'interno dell'ATM
|
Identificazione dei cicli di vita del processo
Scopo
|
Per identificare quando i processi e i thread vengono creati ed eliminati.
|
Ciascun processo o thread del controllo deve essere creato ed eliminato. In un'architettura a processo singolo, la
creazione del processo si verifica quando l'applicazione viene avviata e l'eliminazione del processo quando
l'applicazione viene terminata. Nelle architetture a più processi, i nuovi processi (o thread) vengono tipicamente
generati o duplicati dal processo iniziale creato dal sistema operativo quando l'applicazione viene avviata. Anche tali
processi devono essere eliminati in modo esplicito.
La sequenza degli eventi che porta alla creazione ed eliminazione del processo deve essere determinata e documentata,
così come il meccanismo per la creazione ed eliminazione.
Esempio
Nello sportello automatico ATM (Automated Teller Machine), viene avviato un processo principale che è responsabile per
il coordinamento della funzionalità dell'intero sistema. Tale processo produce un numero di thread di controllo
subordinati per controllare le diverse parti del sistema: le unità nel sistema e gli eventi provenienti dal cliente e
dalla rete ATM. La creazione di questi processi e thread può essere mostrata con classi attive in UML e la
creazione delle istanze di tali classi attive può essere mostrata in un diagramma di sequenza, come riportato di
seguito:
Creazione dei processi e thread durante l'inizializzazione del sistema
|
Identificazione dei meccanismi di comunicazione dei processi interni
Scopo
|
Per identificare le modalità di comunicazione dei processi e thread.
|
I meccanismi IPC (Inter-process communication) abilitano l'invio dei messaggi tra gli oggetti che vengono eseguiti in
processi separati.
I meccanismi tipici di comunicazione dei processi interni includono:
-
Memoria condivisa, con o senza semafori per garantire la sincronizzazione.
-
Rendezvous, soprattutto quando supportato direttamente da un linguaggio come Ada
-
Semafori, utilizzati per bloccare l'accesso simultaneo alle risorse condivise
-
Passaggio di messaggi, sia punto a punto che punto a più punti
-
Caselle postali
-
RPC - Chiamate di procedure remote
-
Trasmissione di eventi - utilizzando un "bus software" ("architettura del bus di messaggi")
La scelta del meccanismo IPC cambierà il modo in cui verrà modellato il sistema; in "un'architettura bus del
messaggio", ad esempio, non sono richieste associazioni esplicite tra oggetti per inviare i messaggi.
|
Allocazione delle risorse di coordinamento dei processi interni
Scopo
|
Per allocare scarse risorse
Per anticipare e gestire potenziali colli di bottiglia delle prestazioni
|
Sono solitamente rari i meccanismi di comunicazione dei processi interni. I semafori, la memoria condivisa e le caselle
postali sono solitamente prefissati in dimensione o numero e non possono essere incrementati senza un costo
significativo. L'RPC, i messaggi e le trasmissioni di eventi richiedono in modo crescente una larghezza di banda rete
scarsa. Quando il sistema supera la soglia di una risorsa, subisce di solito un calo non lineare delle prestazioni: una
volta consumata una risorsa scarsa, le successive richieste della risorsa avranno probabilmente un esito non
desiderato.
Se non sono disponibili le risorse scarse, occorre considerare diverse strategie:
-
ridurre la necessità delle risorse scarse mediante riduzione del numero di processi
-
cambiare l'utilizzo delle risorse scarse (per uno o più processi, scegliere una diversa e meno scarsa risorsa da
utilizzare per il meccanismo IPC)
-
aumentare la quantità delle risorse scarse (ad esempio, aumentando il numero di semafori). Ciò può essere
effettuato relativamente per piccole modifiche, ma spesso determina degli effetti collaterali o presenta dei limiti
prefissati.
-
condividere le risorse scarse (ad esempio, allocando la risorsa solo quando è richiesta e rilasciandola appena
terminato). Quest'operazione è costosa e può solo prevenire la mancanza di risorse.
Indipendentemente dalla strategia scelta, le attività del sistema dovrebbero degradare lentamente (anziché subire
un'interruzione) e fornire un feedback sufficiente all'amministratore di sistema per consentire la risoluzione del
problema (se possibile) nel campo una volta distribuito il sistema.
Se il sistema richiede una particolare configurazione dell'ambiente di runtime per poter aumentare la disponibilità di
una risorsa critica (controllo frequente mediante riconfigurazione del kernel del sistema operativo), occorre che
l'installazione del sistema venga eseguita automaticamente oppure che il responsabile del sistema svolga queste
operazioni prima che il sistema diventi operativo. Ad esempio, potrebbe essere necessario riavviare il sistema prima di
rendere effettiva la modifica.
|
Associazione dei processi all'ambiente di implementazione
Scopo
|
Per associare i "flussi di controllo" ai concetti supportati dall'ambiente di implementazione.
|
I processi concettuali devono essere associati a specifiche costruzioni nell'ambiente operativo. In moti ambienti
esistono diversi tipi di processi, molto spesso processi e thread. Le scelte saranno effettuate in base al livello di
dipendenza (i processi sono autonomi, mentre i thread vengono eseguiti nel contesto di un processo racchiuso) e ai
requisiti delle prestazioni del sistema (la comunicazione interna del processo tra i thread è solitamente più veloce e
più efficiente rispetto a quella tra i processi).
In molti sistemi, potrebbe essere presente un numero massimo di thread per processo o di processi per nodo. Questi
limiti non sono assoluti, ma possono limiti pratici imposti dalla disponibilità delle risorse scarse. I thread e
processi già in esecuzione su un nodo di destinazione devono essere presi in considerazione insieme ai thread e
processi presentati nell'architettura del processo. Occorre tenere in considerazione i risultati della fase precedente,
Allocazione delle risorse di coordinamento interne del
processo, quando la mappatura viene eseguita per garantire che non venga creato un nuovo problema sulle
prestazioni.
|
Associazione degli elementi di progettazione ai thread di controllo
Scopo
|
Per determinare quali thread delle classi di controllo e dei sottosistemi devono essere eseguiti.
|
Le istanze di un dato sottosistema o classe devono essere eseguite all'interno di almeno un thread di controllo
che fornisce l'ambiente di esecuzione per la classe o il sottosistema; di fatto possono essere eseguite in numerosi
processi differenti.
Con l'utilizzo di due diverse strategie simultaneamente, è possibile determinare la "giusta" quantità di concorrenza e
definire la "corretta" serie di processi:
Inside-out (dall'interno verso l'esterno)
-
A partire del modello di progettazione, le classi di gruppo ed i sottosistemi uniti in delle serie di elementi di
cooperazione che (a) collaborano tra loro strettamente e (b) devono essere eseguite nello stesso thread di
controllo. Prendere in considerazione l'impatto che ne consegue l'introduzione della comunicazione interna del
processo all'interno di una sequenza di messaggi prima di suddividere gli elementi in thread di controllo separati.
-
Contrariamente, separare le classi ed i sottosistemi che non interagiscono, collocandoli in diversi thread di
controllo.
-
Questa operazione di raccolta in un cluster procede finché il numero di processi non è stato ridotto al minimo
possibile che comunque consente la distribuzione e l'uso delle risorse fisiche.
Outside-in (dall'esterno verso l'interno)
-
Identificare le emissioni esterne a cui il sistema deve rispondere. Definire un thread di controllo separato per
gestire ciascuna emissione e un thread di controllo separato per fornire ciascun servizio.
-
Utilizzare l'integrità dei dati e i vincoli di serializzazione per ridurre questa serie iniziale di thread di
controllo al numero supportato dall'ambiente di esecuzione.
Non esiste un processo deterministico e lineare che conduce a una vista processi ottimale; sono richieste poche
iterazioni per raggiungere un compromesso accettabile.
Esempio
Il seguente diagramma illustra in che modo le classi all'interno dell'ATM vengono distribuite tra i processi ed i
thread nel sistema.
Mappatura delle classi con i processi per lo sportello automatico ATM
|
|
Proprietà
Ricorrenze multiple |  |
Attivato da evento |  |
In corso |  |
Facoltativo |  |
Pianificato |  |
Ripetibile |  |
Ulteriori informazioni
Concetti |
|
Linee guida |
|
Guida al tool |
|
© Copyright IBM Corp. 1987, 2006. Tutti i diritti riservati.
|
|