Domanda

Qualcuno potrebbe spiegarmi la sincronizzazione delle condizioni?

Anche un esempio (preferibilmente in C#) sarebbe molto apprezzato.

È stato utile?

Soluzione

Sembra che il tuo professore sta parlando di threading. Threading consente ai programmi di computer per fare più di una cosa alla volta. L'atto di avvio di un nuovo thread, mentre uno è già in esecuzione è chiamato "girare un thread" di programmatori di computer.

Le discussioni possono condividere lo stesso spazio di memoria. Condizione di sincronizzazione (o semplicemente sincronizzazione) è un qualsiasi meccanismo che protegge le aree di memoria venga modificato da due fili differenti allo stesso tempo.

Diciamo che si sta fuori a fare shopping, e la moglie è a casa pagare le bollette. Questo è un esempio ingenua, e in realtà non funziona in questo modo nella vita reale, ma servirà come una semplice illustrazione.

La vostra moglie sta pagando un disegno di legge in linea. Allo stesso tempo, si sta strisciare la carta di credito al negozio di alimentari. Entrambi gli atti coinvolgono spostare il denaro dal tuo conto corrente. Per simulare questa attività, scriviamo il seguente codice:

public class MyBanking
{
    static double myAccountBalance;
    //
    public void DebitAccount(double debitAmount)
    {
        Console.Writeline("Your Old Balance is: " + myAccountBalance.ToString());
        Console.Writeline("Your Debit is:       " + debitAmount.ToString());
        myAccountBalance = myAccountBalance - amount;
        Console.Writeline("Your New Balance is: " + myAccountBalance.ToString());
    }
}

Ipoteticamente, tua moglie è in esecuzione una sola istanza ( "copia") di questa classe su un filo, si esegue un'istanza su un altro thread. La variabile myAccountBalance è dichiarata static per consentirgli di essere condiviso tra le due istanze in esecuzione (tu e tua moglie dispone di un solo conto corrente).

Fate il vostro debito chiamando il codice come questo:

MyBanking bankingObject = new MyBanking();
bankingObject.DebitAccount(100);

Il tuo moglie fa il suo debito al tempo stesso:

MyBanking bankingObject = new MyBanking();
bankingObject.DebitAccount(50);

Che cosa succede se il tuo thread viene interrotto dal filo di tua moglie dopo che il vecchio equilibrio viene stampato sullo schermo, ma prima che il nuovo equilibrio viene stampato? filo di tua moglie addebita il conto e restituisce il controllo di nuovo al vostro thread. Tua moglie vede questo sullo schermo:

Your Old Balance is: 2000
Your Debit is:       50
Your New Balance Is: 1950

Quando il computer stampa il nuovo equilibrio sul vostro schermo, sarà sbagliato, perché di debito di tua moglie sarà stato contato anche. Si vedrà qualcosa di simile:

Your Old Balance is: 2000
Your Debit is:       100
Your New Balance Is: 1850

Per risolvere questo problema, ci circondiamo il nostro codice il metodo con una dichiarazione di blocco. L'istruzione lock fa sì che tutti gli altri thread per aspettare il nostro esempio per terminare Il nuovo codice simile a questo:.

public class MyBanking
{
    static double myAccountBalance;
    //
    public void DebitAccount(double debitAmount)
    {
        lock (this)
        {
            Console.Writeline("Your Old Balance is: " + myAccountBalance.ToString());
            Console.Writeline("Your Debit is:       " + debitAmount.ToString());
            myAccountBalance = myAccountBalance - amount;
            Console.Writeline("Your New Balance is: " + myAccountBalance.ToString());
        }
    }
}

filo di tua moglie sarà ora attendere il vostro codice all'interno l'istruzione lock per terminare l'esecuzione, prima che il codice di tua moglie inizia l'esecuzione. Il tuo nuovo equilibrio sarà ora corretto, perché non c'è più la possibilità di filo di tua moglie modificare l'equilibrio mentre si completa la transazione. Sullo schermo, ora vedrete questo:

Your Old Balance is: 2000
Your Debit is:       100
Your New Balance Is: 1900

Il tuo moglie vedrà questo:

Your Old Balance is: 1900
Your Debit is:       50
Your New Balance Is: 1850

Questa è la sincronizzazione.

Altri suggerimenti

Fondamentalmente è un modello di progettazione per i thread che necessitano

a) sincronizzare l'accesso a una risorsa

b) a volte attende altri thread finché non viene soddisfatta una determinata condizione

Lo chiedi in un contesto C#, .NET fornisce supporto per questo con Monitor.Wait e Monitor.Pulse (e con wrapper attorno a vari oggetti Win32 come WaitEventhandle).

Ecco un bel esempio di coda su SO.

I principali dettagli tecnici sono:

lock(buffer)  // is Monitor.Enter(buffer) ... finally Monitor.Leave(buffer)
{
   while (buffer.Count < 1)
   {
      Monitor.Wait(buffer); 
   }
   ...
}

Nota come c'è un'attesa bloccata lì dentro.Sembra una situazione di stallo ma Wait rilascerà il blocco mentre è in attesa.Il codice all'interno del lock() { } ha ancora accesso esclusivo al buffer quando viene eseguito.

E poi un altro thread deve segnalare quando inserisce qualcosa nel buffer:

Monitor.Pulse(buffer);

Il codice di cui sopra è quasi corretto, ma in realtà è sbagliato. Utilizzando lock(this), si blocca solo l'istanza della classe MyBanking, ma tua moglie si blocca la sua. Per bloccare l'accesso alla variabile condivisa o si può bloccare il tipo (vale a dire lock(typeof(MyBanking))) oppure è possibile introdurre una nuova variabile condivisa e bloccare che (non è possibile bloccare un int così tipicamente persone a creare un oggetto come segue.

class MyBanking
{
    static object lockObj = new object();
    static double myAccountBalance;
    public void DebitAccount(double debitAmount)
    {
        lock (lockObj)

La sincronizzazione è stato chiaramente spiegato già. Tuttavia, Sincronizzazione condizione impone espressamente che un processo / thread esegue solo dopo una condizione è verificata. Tipicamente, la condizione sarà che qualche altro processo / thread è già eseguito.

Nell'esempio di addebito un account e la visualizzazione del saldo. Se la visione del vostro equilibrio è stato un metodo sincronizzato separato e abbiamo voluto visualizzare il saldo solo dopo che il tuo account è stato addebitato, allora questo richiederebbe la sincronizzazione condizioni.

Sincronizzazione condizione è molto ben descritto da produttore-consumatore il problema .

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top