Co @synchronized () robi jako metoda pojedyncza w celu C?

87

Właśnie stworzyłem metodę singleton i chciałbym wiedzieć, co @synchronized()robi ta funkcja , ponieważ często jej używam, ale nie znam znaczenia.

max_
źródło

Odpowiedzi:

119

Deklaruje krytyczną sekcję wokół bloku kodu. W kodzie wielowątkowym @synchronizedgwarantuje, że tylko jeden wątek może wykonywać ten kod w bloku w danym momencie.

Jeśli nie jesteś świadomy tego, co robi, prawdopodobnie Twoja aplikacja nie jest wielowątkowa i prawdopodobnie nie musisz jej używać (zwłaszcza jeśli sam singleton nie jest bezpieczny dla wątków).


Edycja: dodanie dodatkowych informacji, których nie było w oryginalnej odpowiedzi z 2011 roku.

@synchronizedDyrektywy zapobiega wielu nici z wejściem na obszar kodu, który jest zabezpieczony przez @synchronizeddyrektywę odnoszące się do tego samego obiektu . Obiekt przekazany do@synchronizeddyrektywy jest obiektem używanym jako „blokada”. Dwa wątki mogą znajdować się w tym samym chronionym regionie kodu, jeśli inny obiekt jest używany jako zamek, a także możesz chronić dwa zupełnie różne obszary kodu przy użyciu tego samego obiektu co zamek.

Ponadto, jeśli zdarzy ci się przejść niljako obiekt blokujący, zamek w ogóle nie zostanie przyjęty.

John Calsbeek
źródło
14
Kilka ważnych punktów: 1) Jeśli użyjesz w @synchronizednim wskaźnika zerowego , nic nie da - pozostaniesz bez ochrony. 2) @synchronizedjest powolny .
Hot Licks
Ta odpowiedź jest myląca i nie powinna być akceptowaną odpowiedzią. Chociaż to, co mówi, czasami byłoby poprawne (o ile token przekazany do zsynchronizowanego jest tym samym obiektem we wszystkich wątkach), jest myląco niekompletny. synchronized zapobiega jednoczesnemu wykonywaniu dowolnej liczby powiązanych sekcji kodu, a nie tylko „tego kodu w bloku”. Parametr do synchronizacji skutecznie określa, które sekcje kodu (lub „bloki”, jak nazywa je odpowiedź) są chronione przed jednoczesnym dostępem.
Arda
@Arda Masz całkowitą rację. Dodałem trochę więcej informacji i link do dokumentacji Apple na temat @synchronized.
John Calsbeek,
@JohnCalsbeek, odpowiedź wygląda teraz znacznie lepiej. Kciuki ode mnie.
Arda
@HotLicks jest interesujące, aby to podkreślić, ale jeszcze lepiej byłoby krótko powiedzieć, jakie mogą być alternatywy (linki?)
itMaxence
43

Z dokumentacji Apple tutaj i tutaj :

Dyrektywa @synchronized to wygodny sposób na tworzenie blokad mutex w locie w kodzie Objective-C. Dyrektywa @synchronized robi to samo, co każda inna blokada mutex - uniemożliwia różnym wątkom uzyskanie tej samej blokady w tym samym czasie.

Dokumentacja dostarcza wielu informacji na ten temat. Warto poświęcić trochę czasu na przeczytanie go, zwłaszcza biorąc pod uwagę, że używasz go, nie wiedząc, co robi.

csano
źródło
26

@synchronizedDyrektywa jest wygodnym sposobem na stworzenie MUTEX zamki w locie w Objective-C kodu.

@synchronizedDyrektywa robi to, co każda inna blokada mutex zrobi, to zapobiega różne wątki z nabycia tej samej blokady w tym samym czasie.

Składnia:

 @synchronized(key) 
 { 
  // thread-safe code 
 }

Przykład:

 -(void)AppendExisting:(NSString*)val
{
  @synchronized (oldValue) {
      [oldValue stringByAppendingFormat:@"-%@",val];
  }
}

Teraz powyższy kod jest całkowicie bezpieczny dla wątków. Teraz wiele wątków może zmienić wartość.

Powyższe to tylko niejasny przykład ...

Durai Amuthan.H
źródło
3
Czy nie powinno to być @synchronized (oldValue)?
Joel,
Albo nawet @synchronized(val, oldValue) { ... }?
Valentin Shergin,
Nie jestem pewien, czy kiedykolwiek widziałem jakiś schemat, który był „całkowicie bezpieczny dla wątków”. Musisz przynajmniej wiedzieć, co robisz, a nie tylko ślepo kopiować skądś kod.
Hot Licks
Ale przypuszczam, że powyższy kod jest mimo wszystko „całkowicie bezpieczny dla wątków”, ponieważ nie robi absolutnie nic.
Hot Licks
6

@ Zsynchronizowany blok automatycznie obsługuje blokowanie i odblokowywanie za Ciebie . @synchronize masz niejawną blokadę skojarzoną z obiektem, którego używasz do synchronizacji. Oto bardzo pouczająca dyskusja na ten temat. Proszę śledzić. Jak @synchronized blokuje / odblokowuje w Objective-C?

abdus.me
źródło
-2

@synchronizedjest thread safemechanizmem. Fragment kodu zapisany w tej funkcji staje się częścią critical section, do której może być wykonywany tylko jeden wątek naraz.

@synchronizestosuje blokadę niejawnie, podczas gdy NSLockstosuje ją jawnie.

Zapewnia tylko bezpieczeństwo nici, a nie gwarantuje tego. Chodzi mi o to, że wynajmujesz doświadczonego kierowcę do swojego samochodu, ale to nie gwarantuje, że samochód nie spotka się z wypadkiem. Jednak prawdopodobieństwo pozostaje najmniejsze.


źródło
2
To jest całkowicie błędne. dispatch_once NIE robi tego samego co @syncrhonized, może być substytutem TYLKO w ramach alokacji singletona.
jugutier