Risposte:
Giusto per essere sicuri che siamo sulla stessa pagina, prima consideriamo queste tre definizioni:
Definizione. Test-and-set è un'istruzione di lettura-modifica-scrittura su alcuni registri binari (diciamo solo che 0 e 1 sono valori possibili) in cui un thread ottiene il vecchio valore e scrive 1.
Definizione. Il consenso viene raggiunto tra thread se tutti i n thread decidono sullo stesso valore (requisito di coerenza) e tutti i thread decidono su un valore che è stato effettivamente proposto da uno dei thread (requisito di validità).
Defintion. Un protocollo di consenso è gratuito se ogni chiamata a un metodo termina in un numero finito di passaggi.
Ora segui due schizzi di prova.
Rivendicazione 1. Il numero di consenso di test-and-set è almeno 2. Prova. Supponiamo di avere due thread 0 e 1 che devono raggiungere il consenso. Potremmo farlo lasciando che ogni thread segua il protocollo di consenso seguente:
Puoi verificare che il consenso e l'attesa siano soddisfatti.
(Per la prossima prova, annetterò alcune prove e definizioni perché penso che renderà più facile seguirle.)
Rivendicazione 2. Il numero di consenso di test-and-set è al massimo 2. Prova. Per contraddizione. Supponiamo di avere tre fili , B e C che desiderano decidere su valori un , b e c , rispettivamente, e che abbiamo qualche priva di attesa valido protocollo di consenso che viene implementato usando test-and-set (e atomica legge e scrive ).
Possiamo visualizzare il processo di consenso come un albero diretto, in cui:
Definizione. Lascia che uno stato sia multivalente se l'esito del processo di consenso non è ancora determinato. In altre parole, non tutti i possibili intrecci delle mosse rimanenti portano allo stesso risultato. Lascia che uno stato sia univalente quando viene determinato il risultato del processo di consenso .
La radice è multivalente. Prova. Se è attivo solo un thread e gli altri thread rimangono inattivi per sempre, allora X finirà in un numero finito di passaggi (garantito dall'ipotesi di attesa senza schermo) e deciderà x (poiché ha accesso solo a questo valore e al suo decisione soddisferà il requisito di validità del consenso). Così, per la nostra situazione, una , b e c sono tutti i risultati possibili. ◻
Definizione. Lascia che uno stato critico sia uno stato multivalente, con la proprietà aggiuntiva che una mossa di determinerà a e una mossa di B determinerà b .
Esiste uno stato critico. Prova. Dall'alto sappiamo che iniziamo in uno stato multivalente. Lascia che non si muova affatto. Finché A o B non costringono l'albero a uno stato univalente, lascia che faccia una mossa. Wait-freeness garantisce che l'albero è finito, quindi ad un certo punto si deve incontrare uno stato critico. ◻
Consideriamo ora uno scenario in cui siamo in uno stato critico. Vi sono almeno due possibilità:
1) fa la sua mossa (determinando così a ) e si ferma. B quindi fa la sua mossa e si ferma. Il prossimo C viene eseguito fino al termine, alla fine decidendo a .
2) fa la sua mossa (determinando in tal modo b ) e si ferma. Il prossimo C viene eseguito fino al termine, decidendo infine b . A non fa una mossa.
Poiché letture e scritture atomiche hanno il consenso numero 1, le mosse di e B dovevano essere istruzioni di prova e impostazione sullo stesso registro (se i registri sono diversi, allora C non sarebbe in grado di dire l'ordine in cui A e Le mosse di B sono avvenute). Dal punto di vista di C , quindi, gli scenari 1 e 2 sono indistinguibili, quindi dobbiamo avere che C decida sia a che b . Questo è impossibile. ◻
Che l'istruzione test-and-set abbia il consenso numero 2 segue sia le rivendicazioni 1 che 2.
L'articolo di Wikipedia ha un riferimento che risponde alla tua domanda, ma forse non vuoi leggere quel documento di 26 pagine. Darò una versione semplificata della dimostrazione (abbastanza tecnica), dimostrando che test-and-set non può risolvere il consenso binario per 3 processi. Questo tipo di argomento è ampiamente utilizzato per dimostrare i numeri di consenso.
Supponiamo di avere un algoritmo di consenso che utilizza i registri TAS per 3 processi.
In qualsiasi momento, ogni processo avrà una mossa (istruzione) pronta per essere eseguita. Quale delle tre istruzioni verrà eseguita non è deterministica.
Supponiamo che siamo in uno stato bivalente (uno stato in cui sia ancora possibile una decisione 0 o 1) e qualunque sia il processo che si sposta successivamente, lo stato successivo sarà univalente. Tale stato deve infine essere raggiunto a causa della condizione di attesa libera.
Supponiamo (wlg) che se il processo 1 si sposta, lo stato sarà 0-valente e che se il processo 2 si sposta, lo stato sarà 1-valente. Entrambe le mosse devono essere un'operazione TAS (o almeno: una sorta di scrittura) sullo stesso registro, poiché se fossero operazioni TAS su registri distinti non potremmo dire se il processo 1 si è spostato per primo o se il processo 2 si è spostato per primo.
Consideriamo queste due possibili esecuzioni:
Dal punto di vista del processo 3, questi stati sono indistinguibili poiché vede solo il valore scritto dal processo 2. Tuttavia, nel primo caso dovrebbe dare 0 come output e nel secondo 1 come output. Chiaramente, questa è una contraddizione.
I processi 1 e 2 possono decidere tra loro quali si sono mossi per primi (perché possono vedere quale valore era nel registro prima della loro scrittura) ma un terzo processo spettatore non può.
Un altro modo per dimostrare che test-and-set non può essere usato per risolvere il consenso di 3 processori è quello di mostrare che test-and-set può essere implementato usando il consenso di 2 processori. Quindi, supponendo che test-and-set possa risolvere il consenso di 3 processori porta a una contraddizione: supponiamo che test-and-set sia in grado di risolvere il consenso di 3 processori; quindi sostituendo test-and-set con la sua implementazione usando il consenso a 2 processori si ottiene un'implementazione del consenso a 3 processori usando il consenso a 2 processori, il che è impossibile. Quindi test-and-set non può risolvere il consenso di 3 processori.
Per implementare test-and-set per n-processori usando il consenso a 2 processori, lascia che i processori determinino un vincitore del test-and-set usando un torneo in cui ogni partita viene implementata usando il consenso a 2 processori (in una partita, i processori proporre il proprio identificatore e il risultato del consenso dice loro chi vince).
In senso pratico una definizione di consenso meno rigorosa potrebbe essere sufficiente (qui la chiamo consenso leggero):
Definizione . Il consenso alla luce viene raggiunto tra n thread sef (a) ogni thread decide sullo stesso valore o il valore è sconosciuto per esso, (b) almeno un thread conosce il valore e (c) questo valore è stato effettivamente proposto da uno dei i fili.
Quindi questo consenso nel suo senso più leggero permette che alcuni thread non conoscano il consenso, il valore che viene deciso.
Corollario : in questo senso più leggero test-and-set ha un numero infinito di consenso per la luce.
Affermazione : questo senso più leggero è pratico. Ad esempio, per selezionare il thread per accedere alla sezione critica non è necessario creare consenso in senso stretto. Vale a dire: ogni thread deve sapere se è stato selezionato o meno, tuttavia se non è selezionato, non dovrà sapere quale è stato selezionato. In altre parole, per l'esclusione reciproca non è necessario il rigoroso consenso, la luce è sufficiente.