Home Hardware Networking Programmazione Software Domanda Sistemi
Conoscenza del computer >> hardware >> .

Quali sono le differenze tra semafori e monitor nella programmazione simultanea?

Sia i semafori che i monitor sono primitivi di sincronizzazione utilizzati nella programmazione simultanea per gestire l'accesso alle risorse condivise e prevenire le condizioni di gara. Tuttavia, differiscono nella loro struttura, applicazione e come vengono utilizzati. Ecco una ripartizione delle differenze chiave:

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