W Objective-C masz rozróżnienie między właściwościami atomowymi i nieatomowymi:
@property (nonatomic, strong) NSObject *nonatomicObject;
@property (atomic, strong) NSObject *atomicObject;
Z mojego zrozumienia można bezpiecznie odczytywać i zapisywać właściwości zdefiniowane jako atomowe z wielu wątków, podczas gdy pisanie i uzyskiwanie dostępu do właściwości nieatomowych lub ivars z wielu wątków w tym samym czasie może skutkować niezdefiniowanym zachowaniem, w tym błędami złego dostępu.
Więc jeśli masz taką zmienną w Swift:
var object: NSObject
Czy mogę bezpiecznie odczytywać i zapisywać w tej zmiennej równolegle? (Bez rozważania rzeczywistego znaczenia robienia tego).
objective-c
swift
lassej
źródło
źródło
@atomic
lub@nonatomic
. lub domyślnie atomic. (Swift jest tak niekompletny, nie możemy teraz wiele powiedzieć)atomic
generalnie nie jest uważany za wystarczający do bezpiecznej dla wątków interakcji z właściwością, z wyjątkiem prostych typów danych. W przypadku obiektów zazwyczaj synchronizuje się dostęp między wątkami za pomocą blokad (np.NSLock
Lub@synchronized
) lub kolejek GCD (np. Kolejka szeregowa lub kolejka współbieżna ze wzorcem „czytnik-zapisujący”).atomic
nie zapewnia bezpieczeństwa wątków dla obiektów; oraz (b) jeśli ktoś właściwie używa jednej z wyżej wymienionych technik synchronizacji w celu zapewnienia bezpieczeństwa wątków (między innymi, zapobieganie jednoczesnemu odczytowi / zapisowi), kwestia atomowa jest dyskusyjna. Ale nadal potrzebujemy / chcemy tego dla prostych typów danych, gdzieatomic
ma realną wartość. Dobre pytanie!Odpowiedzi:
Jest bardzo wcześnie, aby założyć, że nie jest dostępna dokumentacja niskiego poziomu, ale można uczyć się od montażu. Disassembler hopper to świetne narzędzie.
Używa
objc_storeStrong
i odpowiednioobjc_setProperty_atomic
dla nieatomowych i atomowych, gdzieużywa
swift_retain
odlibswift_stdlib_core
i najwyraźniej nie ma wbudowanego zabezpieczenia wątków.Możemy spekulować, że dodatkowe słowa kluczowe (podobne do
@lazy
) mogą zostać wprowadzone później.Aktualizacja 20.07.15 : zgodnie z tym postem na blogu na singletonach, środowisko swift może sprawić, że niektóre przypadki będą bezpieczne dla Ciebie, np .:
Aktualizacja 25.05.16 : Wypatruj propozycji szybkiej ewolucji https://github.com/apple/swift-evolution/blob/master/propiments/0030-property-behavior-decls.md - wygląda na to, że tak jest będziesz mógł mieć
@atomic
zaimplementowane zachowanie.źródło
Swift nie ma żadnych konstrukcji językowych związanych z bezpieczeństwem wątków. Zakłada się, że będziesz używać dostarczonych bibliotek do zarządzania bezpieczeństwem wątków. Istnieje wiele opcji implementacji zabezpieczeń wątków, w tym muteksy pthread, NSLock i dispatch_sync jako mechanizm mutex. Zobacz ostatni post Mike'a Asha na ten temat: https://mikeash.com/pyblog/friday-qa-2015-02-06-locks-thread-safety-and-swift.html A więc bezpośrednia odpowiedź na pytanie „Czy Czy czytam i piszę do tej zmiennej równolegle bezpiecznie? ” nie jest.
źródło
Prawdopodobnie jest za wcześnie, aby odpowiedzieć na to pytanie. Obecnie w Swift brakuje modyfikatorów dostępu, więc nie ma oczywistego sposobu na dodanie kodu, który zarządza współbieżnością wokół metody pobierającej / ustawiającej właściwości. Co więcej, język Swift nie wydaje się jeszcze mieć żadnych informacji o współbieżności! (Brakuje również KVO itp.)
Myślę, że odpowiedź na to pytanie stanie się jasna w przyszłych wydaniach.
źródło
willSet
,didSet
- wydaje się być pierwszym krokiem na drodzeDetale
Spinki do mankietów
Wdrożone typy
Główny pomysł
Próbka dostępu atomowego
Stosowanie
Wynik
źródło
Atomic
klasę i uruchom ją za pomocąAtomic().semaphoreSample()
Oto opakowanie właściwości atomowych, którego często używam. Zrobiłem rzeczywisty mechanizm blokujący jako protokół, więc mogłem eksperymentować z różnymi mechanizmami. Wypróbowałem semafory
DispatchQueues
ipthread_rwlock_t
.pthread_rwlock_t
Został wybrany, ponieważ wydaje się mieć najmniejszy narzut i mniejsze szanse na priorytetową inwersji.źródło
Od wersji Swift 5.1 możesz używać opakowań właściwości, aby tworzyć określoną logikę dla swoich właściwości. Oto implementacja atomic wrapper:
Jak używać:
źródło