Bu makale makine çevirisi ayna makalesidir, orijinal makaleye geçmek için lütfen buraya tıklayın.

Görünüm: 46741|Yanıt: 7

[Kaynak] Değişken vs. Kilitli vs. Kilitli

[Bağlantıyı kopyala]
Yayınlandı 27.08.2018 14:40:35 | | |
Diyelim ki birden fazla iş parçacığı tarafından erişilebilen halka açık bir int sayacı alanı içeren bir sınıf var ve bu sayı sadece artar veya azalır.

Bu alan eklenirken, aşağıdaki şemalardan hangisi kullanılmalıdır ve neden?

  • kilit(this.locker) this.counter++;
  • Kilitli.Artış (b. this.counter);
  • Sayaç erişim değiştiricisini public volatile olarak değiştirin


En kötüsü (hiçbiri gerçekten işe yaramıyor)

Sayaç erişim değiştiricisini public volatile olarak değiştirin

Bu yaklaşım aslında hiç güvenli değildir ve değişkenlikle ilgili önemli nokta, birden fazla CPU üzerinde çalışan birden fazla iş parçacığının verileri tamponlaması ve çalıştırılan komutları yeniden düzenlemesidir.

Eğer değişken değilse, CPU A bir değer arttığında, CPU B artan değeri görmek için biraz beklemelidir, bu da sorunlara yol açabilir.

Eğer değişkense, her iki CPU'nun aynı anda aynı değeri görmesini sağlar. Ama çapraz okuma ve yazma işlemlerinden kaçınmıyor.

Bir değişkene değer eklemek aslında üç adım gerektirir

1. Okuma, 2. 3. Yaz

Diyelim ki iş parçacığı A sayacın değerini 1 olarak okuyor ve artmaya hazır değil, sonra iş parçacığı B de sayaç değerini 1 olarak okur ve her iki iş parçacığı da artım ve yazma işlemleri yapmaya başlar. Son sayaçın değeri 2'dir. Bu doğru değil, her iki iş parçacığı da bir artırma işlemi yaptı ve doğru sonuç 3 olmalı. Bu yüzden değişken olarak etiketlemek tamamen güvenli değildir.

Daha iyi

kilit(this.locker) this.counter++;

Bu şekilde güvenli olur (tabii ki bu sayaca erişmek istediğiniz her yeri kilitlemeyi unutmayın). Bu, kilitli kodu başka herhangi bir iş parçacığı çalıştırmasını engeller. Ayrıca yukarıda bahsedilen çoklu CPU komut dizileme sorununu da önler. Sorun şu ki, kilit performansında yavaş ve başka alakasız yerlerde kilitleme kullanırsanız diğer iş parçacıklarını engelleyebilir.

En iyisi

Kilitli.Artış (b. this.counter);

Bu güvenli ve çok verimli. Bir atomda ortada kesinti olmadan üç okuma, artırma ve yazma işlemlerini gerçekleştirir. Çünkü diğer kodları etkilemiyor, başka yerlerde kilitleri hatırlamanıza gerek yok. Ayrıca çok hızlı (MSDN'nin dediği gibi, günümüz CPU'larında genellikle sadece bir komut oluyor).

Ama CPU'nun komut sıralaması sorununu da çözüp çözemeyeceğinden tam emin değilim, yoksa volatile ve bu artışla birlikte mi kullanılması gerekiyor.

Ek: Volatile hangi sorunları iyi çözer?

Volatile çoklu iş parçacığı engelleyemediği için ne yapabilir? İyi bir örnek olarak, iki iş parçacığına sahip olmanız olur; biri her zaman bir değişkene yazar, diyelim ki bu değişken queneLength, diğeri ise her zaman bu değişkenden veri okur. QueueLenght değişken değilse, iş parçacığı A 5 kez okunabilir, ancak iş parçacığı B gecikmiş veri görebilir veya hatta veri yanlış sırayla olabilir. Bir çözüm lock kullanmaktır, ama bu durumda volatile de kullanılabilir. Bu, iş parçacığı B'nin her zaman iş parçacığı A tarafından yazılmış en son verileri görmesini sağlar, ancak bu mantık yalnızca yazarken okumazsanız ve okurken yazmazsanız çalışır. Birden fazla iş parçacığı okuma-değiştirme-yazma işlemleri yapmak istediğinde, Interlocked veya lock kullanmanız gerekir.





Önceki:Java MD5 şifreleme yöntemi
Önümüzdeki:Linq, SQL'de koşullu sorguları not in ve in uygular
Yayınlandı 29.08.2018 16:21:42 |
Merhaba, daha önce yaptığın kod, yüksek chart üst üste yığılmış histogramlar ile delinebilir histogramları birleştiriyor mu? https://jshare.com.cn/demos/hhhhDz?hc-theme=grid-light arayüzünde düzenlenebilen bir kod gönderebilir misiniz diye sormak isterim.
Yayınlandı 29.08.2018 16:22:13 |
Tüm ağ sadece sizin kaynağınız.
Yayınlandı 29.08.2018 16:22:55 |
Çünkü önceki 90 yıl önce mesaj bırakamıyordu. yani
Yayınlandı 29.08.2018 16:40:40 |
İletişim bilgisi eklemek uygun mu? Sizinle görüşmek
 Ev sahibi| Yayınlandı 15.09.2018 13:10:16 |
özel statik int safeInstanceCount = 0; Atomlarla çalışmak
System.Threading.Interlocked.Increment (ref safeInstanceCount); Kendi Kendine Artış 1
System.Threading.Interlocked.Decrement (ref safeInstanceCount); Kendi eksik 1
Yayınlandı 21.05.2020 16:43:54 |
Sahibin paylaşmasını destekle
 Ev sahibi| Yayınlandı 11.06.2020 15:00:16 |
1. Kavram

Çok iş parçacıklı bir ortamda, iş parçacığı zamanlama mekanizmalarıyla kesintiye uğramayan işlemler; Bu işlem başladıktan sonra, arada herhangi bir bağlam değişikliği (başka bir iş başlığına geçmeden) olmadan sonuna kadar çalışır.

2. Sınıf

System.Threading.Interlocked statik sınıfı

3. Yaygın kullanılan fonksiyonlar (diğerlerine bakınız)

1. halka açık statik int Decrement (referans int konumu); Belirtilen değişkenin değerini atomik bir işlem şeklinde ayırın ve sonucu depolayın

lock(obj){i--; }

2. public static int Increment (referans int konum); Belirtilen değişkenin değerini atomik işlem şeklinde artırın ve sonucu depolayın

lock(obj){i++; }
Feragatname:
Code Farmer Network tarafından yayımlanan tüm yazılım, programlama materyalleri veya makaleler yalnızca öğrenme ve araştırma amaçları içindir; Yukarıdaki içerik ticari veya yasa dışı amaçlarla kullanılamaz, aksi takdirde kullanıcılar tüm sonuçları ödemelidir. Bu sitedeki bilgiler internetten alınmakta olup, telif hakkı anlaşmazlıklarının bu siteyle hiçbir ilgisi yoktur. Yukarıdaki içeriği indirmeden sonraki 24 saat içinde bilgisayarınızdan tamamen silmelisiniz. Programı beğendiyseniz, lütfen orijinal yazılımı destekleyin, kayıt satın alın ve daha iyi orijinal hizmetler alın. Herhangi bir ihlal olursa, lütfen bizimle e-posta yoluyla iletişime geçin.

Mail To:help@itsvse.com