Există reguli generale privind/linii directoare pentru ceea ce face metoda thread-safe? Am înțeles că există, probabil, un milion de one-off de situații, dar ceea ce despre în general? E simplu?
Asta este? Asta se aplică pentru metodele statice la fel de bine?
Un singur răspuns, oferit de @Cybis, a fost:
variabilele Locale nu pot fi partajate între fire pentru fiecare fir devine propria sa stivă.
Este faptul că în cazul metodelor statice la fel de bine?
Dacă o metodă este trecut un obiect de referință, nu rupe firul de siguranță? Am'am făcut unele de cercetare, și există o mulțime de acolo despre anumite cazuri, dar am fost în speranța de a fi în măsură să definească, folosind doar câteva reguli, linii directoare de urmat pentru a face sigur că o metodă este thread-safe.
Deci, cred că ultima mea întrebare este: "Este o scurtă listă de reguli care definesc un thread-safe metoda? Dacă da, care sunt acestea?"
EDIT
O mulțime de puncte bune au fost făcute aici. Cred că răspunsul la această întrebare este: "nu Există reguli simple pentru a asigura firul de siguranță." Cool. Bine. Dar în general cred că răspunsul acceptat oferă un scurt rezumat. Există întotdeauna excepții. Așa să fie. Eu pot trăi cu asta.
Dacă o metodă (exemplu sau statice) numai referințe variabile cad în această metodă, atunci acesta este thread-safe, pentru că fiecare subiect are propria sa stivă:
În acest exemplu, mai multe fire-ar putea numi ThreadSafeMethod` simultan fără probleme.
public class Thing
{
public int ThreadSafeMethod(string parameter1)
{
int number; // each thread will have its own variable for number.
number = parameter1.Length;
return number;
}
}
Acest lucru este valabil și în cazul în care metoda de apeluri altă metodă de clasă care numai referință la nivel local luneta variabile:
public class Thing
{
public int ThreadSafeMethod(string parameter1)
{
int number;
number = this.GetLength(parameter1);
return number;
}
private int GetLength(string value)
{
int length = value.Length;
return length;
}
}
Dacă o metodă accesează orice (obiect de stat) proprietăți sau domenii (exemplu sau statice), atunci ai nevoie pentru a folosi încuietori pentru a se asigura că valorile nu sunt modificate de către un alt thread.
public class Thing
{
private string someValue; // all threads will read and write to this same field value
public int NonThreadSafeMethod(string parameter1)
{
this.someValue = parameter1;
int number;
// Since access to someValue is not synchronised by the class, a separate thread
// could have changed its value between this thread setting its value at the start
// of the method and this line reading its value.
number = this.someValue.Length;
return number;
}
}
Tu ar trebui să fie conștienți de faptul că orice parametri trecut la metoda care nu sunt de nici un struct sau imuabil ar putea fi transformată de către un alt fir în afara domeniului de aplicare a metodei.
Pentru a asigura buna concurenta, trebuie să utilizați de blocare.
pentru informații suplimentare a se vedea lock declarație C# de referință și ReadWriterLockSlim.
blocare este cea mai utilă pentru furnizarea de unul la un moment dat funcționalitate,
ReadWriterLockSlim
este util dacă aveți nevoie de mai multe cititoare și singur scriitori.
Dacă o metodă accesează doar variabile locale, l's thread-safe. Asta este?
Absolultely nu. Puteți scrie un program cu o singură variabilă locală accesate dintr-un singur fir care nu este totuși sigură pentru fire:
https://stackoverflow.com/a/8883117/88656
asta Se aplică pentru metodele statice la fel de bine?
Absolut nu.
Un singur răspuns, oferit de @Cybis, a fost: "variabilele Locale nu pot fi partajate între fire pentru fiecare fir devine propria sa stivă."
Absolut nu. Caracteristica distinctivă a unei variabile locale este că acesta este numai vizibile din interiorul locale, domeniul de aplicare, nu că este alocate pe bazin temporar. Este perfect legal și posibil pentru a accesa aceeași variabilă locală din două fire diferite. Puteți face acest lucru prin utilizarea de metode de anonime, lambda, iterator blocuri sau asincron metode.
Este faptul că în cazul metodelor statice la fel de bine?
Absolut nu.
Dacă o metodă este trecut un obiect de referință, nu rupe firul de siguranță?
Poate.
nu'am făcut unele de cercetare, și există o mulțime de acolo despre anumite cazuri, dar am fost în speranța de a fi în măsură să definească, folosind doar câteva reguli, linii directoare de urmat pentru a face sigur că o metodă este thread-safe.
Aveți de gând să trebuie să învețe să trăiască cu dezamăgire. Acesta este un subiect foarte dificil.
Deci, cred că ultima mea întrebare este: "Este o scurtă listă de reguli care definesc un thread-safe metoda?
Nu. După cum ați văzut din exemplul meu de mai devreme un gol metodă poate fi non-thread-safe. Ai putea la fel de bine cere "este o scurtă listă de reguli care asigură o metodă este corect". Nu, nu este. Firul de siguranță este nimic mai mult decât un extrem de complicat, un fel de corectitudine.
Mai mult decât atât, faptul că tu îți pui întrebarea indică neînțelegere fundamentală despre firul de siguranță. Firul de siguranță este o global, nu locale proprietate a unui program. Motivul pentru care este atât de greu pentru a obține dreptul este pentru că trebuie să aveți o cunoaștere completă a filetare comportamentului întregului program în scopul de a asigura siguranța.
Din nou, uita-te la exemplul meu: fiecare metodă este banal. Acesta este modul în care metodele de a interacționa cu fiecare alte la o "global" nivel care face programul impas. Puteți't uita-te la fiecare metodă și verificați-l pe ca "sigur" și apoi așteptăm ca întregul program este în siguranță, mai mult decât orice ai putea concluziona că, deoarece casa ta este fabricat din 100% non-cărămizi cu goluri care casa este, de asemenea, non-gol. Goliciunea unei case este o proprietate globală a întregului lucru, nu un agregat de proprietățile părților sale.
Nu există nici o regulă greu și rapid.
Iată câteva reguli pentru a face codul fir în siguranță .NET și de ce acestea nu sunt reguli bune:
Nu există nici o regulă care face codul thread-safe, singurul lucru care le puteți face este să vă asigurați că codul va funcționa indiferent de câte ori este activ executat, fiecare fir poate fi întrerupt în orice moment, cu fiecare fir fiind în propriul său stat/locație, și asta pentru fiecare funcție (statice sau în alt mod), care este accesarea obiecte comune.