Kural
Şunu sağlayın iş parçacığı güvenli erişimin sağlayın paylaşılan duruma
Paylaşılan değiştirilebilir durum erişilen birden birden fazla iş parçacığı
senkronizasyon senkronizasyon neden olur yarış koşullarına ve çalışma hatalarına
Desteklenen diller: Python, Java, C#Giriş
Birden fazla iş parçacığı, senkronizasyon olmadan paylaşılan değişkenlere erişip bunları değiştirdiğinde, yarış durumları ortaya çıkar. Nihai değer, öngörülemez iş parçacığı yürütme zamanlamasına bağlıdır; bu da veri bozulmasına, hatalı hesaplamalara veya çalışma zamanı hatalarına yol açar. Kilitleme yapılmadan birden fazla iş parçacığı tarafından artırılan bir sayaç, iş parçacıkları eski değerleri okuyup bunları artırdıktan sonra çakışan sonuçları geri yazdıklarından dolayı güncellemeleri kaçıracaktır.
Neden önemli?
Veri bozulması ve hatalı sonuçlar: Yarış durumları, değerlerin tutarsız veya hatalı hale geldiği, fark edilmeyen veri bozulmalarına neden olur. Hesap bakiyeleri yanlış olabilir, stok sayıları negatif çıkabilir veya toplu istatistikler bozulabilir. Bu hatalar, tam olarak iş parçacığı zamanlamasına bağlı oldukları için yeniden üretilmesi zordur.
Sistem kararsızlığı: Paylaşılan duruma senkronize olmayan erişim, uygulamaların çökmesine neden olabilir. Bir iş parçacığı bir veri yapısını değiştirirken başka bir iş parçacığı onu okuyabilir; bu da null işaretçi hataları veya indeks sınırı aşımı gibi istisnalara yol açabilir. Üretim ortamında bu durumlar, yük altında aralıklı çökmeler şeklinde ortaya çıkar.
Hata ayıklama karmaşıklığı: Yarış durumlarının hata ayıklaması, belirsiz olmaları nedeniyle bilindiği üzere oldukça zordur. Bu hata, tek iş parçacıklı testlerde veya düşük yük ortamlarında ortaya çıkmayabilir. Sorunun yeniden canlandırılması, zorlanarak sağlanması zor olan belirli bir iş parçacığı iç içe geçme düzenini gerektirir; bu da sorunların rastgele ortaya çıkıp kaybolmasına neden olur.
Kod örnekleri
❌ Uygun değil:
sınıf BankaHesabı:
def __init__(self):
self.bakiye = 0
def deposit(self, amount):
current = self.balance
# Yarış durumu: başka bir iş parçacığı burada bakiyeyi değiştirebilir
time.sleep(0.001) # İşlem süresini simüle eder
self.balance = current + amount
def withdraw(self, amount):
eğer self.bakiye >= tutar:
current = self.balance
time.sleep(0.001)
self.bakiye = mevcut - tutar
return True
return False
Neden yanlış: Birden fazla iş parçacığının aynı anda deposit() veya withdraw() işlevlerini çağırması, yarış durumlarına yol açar. Her biri 100 $ yatıran iki iş parçacığı, bakiyeyi 0 $ olarak okuyabilir ve ardından her ikisi de 100 $ yazabilir; bu durumda nihai bakiye 200 $ yerine 100 $ olur.
✅ Uygunluk:
ithalat iş parçacığı
sınıf BankAccount:
def __init__(self):
self.__balance = 0
self.__lock = threading.Lock()
@property
def balance(self):
with self.__lock:
return self.__balance
def deposit(self, amount):
with self.__lock:
current = self.__balance
time.sleep(0.001)
self.__balance = current + amount
def withdraw(self, tutar):
with self.__lock:
eğer self.__balance >= amount:
current = self.__balance
time.sleep(0.001)
self.__balance = current - amount
return True
return False
Bunun önemi: Şu threading.Lock() bir seferde yalnızca bir iş parçacığının balance'a erişmesini sağlar. Bir iş parçacığı kilidi tuttuğunda, diğerleri bekler ve bu sayede eşzamanlı değişiklikler önlenir. Özel __bakiye salt okunur olarak @özellik dışarıdan gelen kodların kilit korumasını atlamasını engeller.
Sonuç
Tüm paylaşılan değiştirilebilir durumları, kilitler, semaforlar veya atomik işlemler gibi uygun senkronizasyon öğeleriyle koruyun. Mümkün olduğunda değiştirilemez veri yapılarını veya iş parçacığı yerel depolamayı tercih edin. Senkronizasyon gerektiğinde, çekişmeyi azaltmak ve performansı artırmak için kritik bölümleri en aza indirin.

