Synchronizace threadů
Včera jsem se pokušel napsat příklad, který by demonstroval co se stane, pokud thready využívající sdílený prostředek nejsou synchronizovány. Jak asi každý ví, že se to tam a tam může pokazit, snaží se automaticky myslet tak, aby tomuto nedeterministickému chování předešel. Já jsem však potřeboval napsat příklad, který by toto záměrně porušoval. Pachtil jsem se s tim poměrně dlouho – myslel jsem si, že špatný příklad lehce dokážu vytvořit – a hle, není to tak jednoduché.
Pokud by tedy někdo potřeboval příklad, který by toto ukázal, může využít tento (těžce vymyšlený
):
using System;< ?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /> using System.Collections.Generic; using System.Text; using System.Threading; namespace synchro { class Program { public static int globalni = 0; static void Main(string[] args) { for (int i = 0; i < 5; i++) { ThreadStart ts = new ThreadStart((new Worker()).Run); new Thread(ts).Start(); } Console.ReadKey(); } } class Worker { public Worker() { } public void Run() { //lock(typeof(Program)) { int i = Program.globalni; i++; Thread.Sleep(new Random().Next(2000)); Program.globalni = i; Console.WriteLine(Program.globalni.ToString()); } } } }



There's 4 Comments So Far
December 29th, 2005 at 21:31
Mozno uz tak trochu spim, ale co to vlastne demonstruje? Podla mna sa to bude chovat "kvazikorektne", teda kazdy thread vypise hodnotu o jedna vacsiu ako mal na zaciatku. A to je presne chovanie, ktore by som ocakaval, ked sa pozriem na kod toho threadu.
Ja by som to upravil takto:
int i = Program.globalni;
i++;
Thread.Sleep(new Random().Next(2000)); // ved predsa thread sa moze prerusit kdekolvek, tak preco nie prave tu
Program.globalni++;
Console.WriteLine(Program.globalni.ToString());
Console.WriteLine(i.ToString());
Ale ako to ze nam to nevypisuje to iste, ked na zaciatku boli hodnoty rovnake a u oboch sme iba pripocitali jednotku???
December 29th, 2005 at 22:17
Vsak si to zkus pouzit. Je treba se nad tim zamyslet (bohuzel). Pokud to nechas s tim komentarem, vypise to (pravdepodobne) same jednicky (nebo proste neco nepredvitatelneho (i kdyz u tohohle prikladu asi ty jednicky na 99%), kdyz tam das tu synchronizaci, vypise ti to 1,2,3,4,5.
December 30th, 2005 at 10:45
Ja rozumiem v com je problem, len sa mi to nezda byt dostatocne ukazkove. Ja ked si ten kod precitam (bez locku) tak si ho v hlave prelozim tak, ze vypise cislo o jedna vacsie ako mal na zaciatku a to sa splni. To, ze to s lockom a bez neho robi nieco ine este mnoho nehovori. Mozno to chovanie s lockom je zle. Ale ze sa to sprava "nekorektne" (ako to necakame) je podla mna lepsi priklad.
December 30th, 2005 at 10:51
No, tak kdyz si to ctes bez locku, tak si to precti vicekrat. Potom uvidis, ze to vypisuje uplne kraviny. Pripadne si do te smycky co to startuje dej taky nahodny sleep.
Share your thoughts, leave a comment!