Tutto ciò che un thread fa sono operazioni interleave in modo che parti del processo sembrino sovrapporsi nel tempo. Una macchina single-core con più thread si limita a saltare: esegue piccoli bit di codice da un thread, quindi passa a un altro thread. Un semplice scheduler decide quale thread ha la massima priorità e viene effettivamente eseguito nel core.
Su un computer single-core, in realtà non accade nulla "contemporaneamente". È solo un'esecuzione interlacciata.
Esistono molti, molti modi per ottenere l'interleaving. Molti.
Supponiamo che tu abbia un semplice processo a due thread che utilizza un semplice blocco in modo che entrambi i thread possano scrivere su una variabile comune. Hai sei blocchi di codice.
- T1-prima del blocco
- T1-con serratura
- T1-dopo blocco
- T2 prima del blocco
- T2-con serratura
- T2-dopo blocco
[Questo può essere in un ciclo o avere più blocchi o altro. Tutto ciò che fa è allungarsi, non più complesso.]
Le fasi di T1 devono essere eseguite in ordine (T1-prima, T1-con, T1-dopo) e le fasi di T2 devono essere eseguite in ordine (T2-prima, T2-con, T2-dopo).
Oltre al vincolo "in ordine", questi possono essere interfogliati in qualsiasi modo. Comunque. Potrebbero essere eseguiti come elencato sopra. Un altro ordine valido è (T1-prima, T2-prima, T2-blocco, T1-blocco, T2-dopo, T1-dopo). Ci sono molti ordini validi.
Aspettare.
Questa è solo una macchina a stati con sei stati.
Si tratta di automi a stati finiti non deterministici. L'ordinamento degli stati T1-xxx con stati T2-xxx è indeterminato e non ha importanza. Quindi ci sono posti in cui il "prossimo stato" è un lancio di monete.
Ad esempio, all'avvio di FSM, T1-before o T2-before sono entrambi i primi stati legittimi. Lancia una moneta.
Diciamo che è arrivato T1 prima. Fai quello. Al termine, è possibile scegliere tra T1-with e T2-before. Lancia una moneta.
Ad ogni passo nel FSM ci saranno due scelte (due thread - due scelte) e un lancio di una moneta può determinare quale stato specifico è seguito.