1. Struttura e implementazione:
* Semafori:
* Variabili interi semplici: Nel loro centro, i semafori sono variabili interi a cui si accede e modificati utilizzando operazioni atomiche.
* Due operazioni atomiche: In genere hanno due operazioni primarie:
* `wait ()` (o `p ()` o `acquisito ()`):diminuisce il valore del semaforo. Se il valore diventa negativo, il processo/thread blocca fino a quando il valore semaforo è maggiore o uguale a zero.
* `Signal ()` (o `v ()` o `rilascio ()`):incrementa il valore del semaforo. Se ci sono processi/thread bloccati in attesa sul semaforo, uno di essi è sbloccato.
* Nessuna associazione di dati implicita: I semafori non legano intrinsecamente il meccanismo di sincronizzazione a dati specifici. È possibile utilizzare un semaforo per controllare l'accesso a qualsiasi risorsa condivisa, ma è necessario gestire manualmente l'associazione.
* Monitor:
* Approccio strutturato: I monitor sono costrutti di programmazione più strutturati. Incapsulano:
* Dati condivisi: Variabili che rappresentano la risorsa condivisa protetta.
* Procedure/Metodi: Le operazioni che accedono e modificano i dati condivisi. Queste sono le uniche routine che possono accedere direttamente ai dati condivisi.
* Variabili di condizione: (Importante!) Variabili speciali utilizzate per la segnalazione e l'attesa all'interno del monitor.
* Esclusione reciproca esplicita: I monitor forniscono un'esclusione reciproca implicita. Un solo thread/processo può essere attivo * all'interno * Il monitor in qualsiasi momento. Questa esclusione reciproca viene automaticamente applicata dal monitor stesso.
2. Applicazione dell'esclusione reciproca:
* Semafori:
* Applicazione manuale: I semafori si basano sui programmatori per utilizzare correttamente le operazioni `wait ()` e `signal ()` attorno alle sezioni critiche. Spetta al programmatore garantire che l'esclusione reciproca sia adeguatamente mantenuta. Gli errori possono essere facilmente introdotti. Ad esempio, dimenticare un `segnale () può portare allo stallo. Posizionare `wait ()` o `signal ()` al di fuori della sezione critica prevista può causare problemi di concorrenza.
* Errore incline: Questa applicazione manuale è soggetta a errori. È facile commettere errori che rompono l'esclusione reciproca o causano deadlock.
* Monitor:
* Applicazione implicita: I monitor impongono l'esclusione reciproca *implicitamente *. Il linguaggio/sistema garantisce che un solo thread possa essere attivo all'interno del monitor alla volta. Ciò rende più facile ragionare e meno soggetto a errori. Il compilatore o il sistema di runtime gestisce il blocco e lo sblocco.
3. Sincronizzazione delle condizioni (attesa e segnalazione):
* Semafori:
* Buono generale, ma meno strutturato per le condizioni in attesa: I semafori * possono * essere utilizzati per la sincronizzazione delle condizioni (ad esempio, in attesa che una risorsa sia disponibile). Tuttavia, è un po 'ingombrante. In genere è necessario semafori separati per l'esclusione reciproca e per le condizioni di segnalazione, rendendo il codice più complesso e incline all'errore. È possibile utilizzare il conteggio dei semafori per indicare quante una risorsa sono disponibili.
* Monitor:
* Variabili di condizione: I monitor usano * Variabili di condizione * specificamente per la sincronizzazione delle condizioni. Questi forniscono operazioni come:
* `wait (condizione)`:il thread chiamante rilascia il blocco del monitor e attende la condizione specificata. Il thread è posizionato in una coda associata a quella variabile condizione. Il blocco del monitor viene rilasciato in modo che altri thread possano inserire il monitor.
* `segnale (condizione)`:viene risvegliato un thread in attesa sulla specifica `condizione`. La filettatura segnalata riacquista il blocco del monitor.
* `broadcast (condizione)` (o `segnalall (condizione)`):risveglia tutti i thread in attesa della `condizione 'specificata.
* Struttura migliorata: Le variabili delle condizioni sono strettamente legate al monitor e ai suoi dati condivisi, rendendo più facile la comprensione e ragionare sulla sincronizzazione delle condizioni all'interno del monitor.
4. Proprietà e responsabilità:
* Semafori:
* Nessuna proprietà chiara: Qualsiasi thread può `wait ()` o `segnale ()` su un semaforo. Non esiste un concetto di "possedere" un semaforo.
* Monitor:
* Clear Proprietà: I thread devono immettere il monitor (acquisire implicitamente il blocco del monitor) prima di accedere ai dati condivisi o alle variabili della condizione di segnalazione. Ciò applica un chiaro modello di proprietà.
5. Rientranza:
* Semafori:
* Nessun concetto intrinseco di rientranza: I semafori non sanno se il thread che chiama `wait ()` o `signal ()` contiene già il semaforo. L'uso di un semaforo in modo rena (ad esempio, lo stesso thread acquisisce il semaforo più volte senza rilasciarlo) può facilmente portare a Deadlock.
* Monitor:
* Generalmente non ritenente: I monitor sono generalmente progettati per essere *non retent *. Un thread che contiene già il blocco del monitor non può rientrare nel monitor. Ciò semplifica il ragionamento sullo stato del programma, ma a volte può richiedere un codice di ristrutturazione. Alcune implementazioni monitorano supportano il rientro, ma è meno comune.
In sintesi:
| Caratteristica | Semafori | Monitor |
| ------------------- | ------------------------------------------------- | ------------------------------------------------------------------
| Struttura | Variabili interi semplici | Costrutto strutturato con dati, procedure e variabili di condizione |
| Esclusione reciproca | Manuale (responsabilità del programmatore) | Implicito (applicato dal monitor stesso) |
| Sincronizzazione delle condizioni | Può essere usato, ma meno strutturato | Esplicito con le variabili delle condizioni (attesa, segnale, trasmissione) |
| Errore soggetto a errore | Più soggetto a errori a causa della gestione manuale | Meno soggetto a errori a causa dell'applicazione implicita |
| Proprietà | Nessuna proprietà chiara | Clear Ownership (il thread deve inserire il monitor) |
| Rientranza | Generalmente non considerato | Generalmente non ritenente |
Quando usare ciò:
* Semafori: Sebbene ancora preziosi, i semafori sono spesso visti come una primitiva di livello inferiore. Sono utili quando è necessario un semplice meccanismo di conteggio o quando i requisiti di sincronizzazione sono molto semplici. Sono anche utili nei sistemi in cui i monitor non sono supportati in modo nativo.
* Monitor: I monitor sono preferiti quando si tratta di scenari di sincronizzazione più complessi. Il loro approccio strutturato, l'esclusione reciproca implicita e le variabili delle condizioni rendono più facile scrivere un codice concorrente corretto e mantenebile. I monitor sono adatti per proteggere le strutture di dati condivise e l'implementazione di modelli di sincronizzazione. Molti linguaggi di programmazione moderni forniscono supporto integrato per monitor o costrutti simili (ad esempio, la parola chiave `sincronizzata 'di Java e` wait () `,` notify () `,` notifyall () `metodi o Python's` `thread.lock` e` threading.condition`).
Esempio (concettuale - lingua non specifica):
Esempio di semaforo (concettuale):
`` `
semaforo mutex =1; // semaforo binario per esclusione reciproca
Semaforo ResourceAvailable =0; // Conteggio del semaforo per le risorse disponibili
// thread 1 (produttore)
wait (mutex);
// Accesso e modifica la risorsa condivisa
// Aggiungi risorsa
segnale (mutex);
segnale (risorse vavillabile); // segnala che una risorsa è ora disponibile
// thread 2 (consumatore)
wait (risorse aceabilizzabile); // Aspetta che una risorsa sia disponibile
wait (mutex);
// Accesso e modifica la risorsa condivisa
// Consuma risorsa
segnale (mutex);
`` `
Esempio di monitoraggio (concettuale):
`` `
Monitora myMonitor {
Dati condivisi:...;
condizione di risorse vavillabili;
Method AccessResource () {
// Acquisisci implicitamente il blocco del monitor
mentre (la risorsa non è disponibile) {
wait (risorse aceabilizzabile); // rilascio del blocco del monitor, attendere a condizione
}
// accedi e modifica i dati condivisi
// ...
segnale (risorse vavillabile); // Discussione del segnale
// rilascia implicitamente il blocco monitor quando il metodo ritorna
}
Method adDreSource () {
// Acquisisci implicitamente il blocco del monitor
// Aggiungi risorsa ai dati condivisi
segnale (risorse vavillabile); // Discussione del segnale
// Blocco monitor rilascia implicitamente
}
}
`` `
Nell'esempio di monitor, l'esclusione reciproca viene gestita automaticamente dal monitor, rendendo meno incline agli errori. Le variabili delle condizioni forniscono un modo più strutturato per gestire l'attesa e la segnalazione rispetto all'utilizzo diretto dei semafori a questo scopo.
hardware © www.354353.com