Bir önceki ders videosunda, tüketici iş parçacığı için sözde kodun nasıl yazılacağını
ve bir iş parçacığı üretmek için sözde kodun nasıl yazılacağını öğrendik, böylece
tüketici ve üretici buğday ve sigma gözlerini kullanarak birbirleriyle koordine olabilirler, değil
mi? Tüketici tarafında S1, S2, S3, S4, S5 başlık numaralarını tartışacağız ve
üretici tarafında S6, S7, S8, S9 sekmelerini tartışacağız ve ayrıca bu
üst ve tüketici ve üretici taraflarının her birinin alaka düzeyini tartışacağız.
Ancak üretici ve tüketici iş parçacığı arasındaki koordinasyonu temsil eden
bu iki sözde kod parçasında hala bir boşluk var.
Bu nedenle, yapacağımız bu derste, boşluğun ne
olduğunu ve bu boşluğun nasıl onarılabileceğini tartışacağız.
Hatırlayın, öncelikli hedeflerimizden biri Q'yu boş bulmaya çalışan tüketicinin
kendisini bloke etmesiydi, değil mi? Yani tüketici, S4 adım
numarasını yalnızca kill'in boş olmadığı garanti edildiğinde çalıştırmalıdır,
değil mi? Eğer bir şekilde tüketici tehdidimiz boş
bir kuyrukta S4 numaralı adımı çalıştırırsa, o zaman
programın bu özel durumunu sorunlu durum olarak değerlendiririz.
Değil mi? Şimdi bu derste, size üretici ve tüketici
iş parçacığının bu sudoku koğuşuyla, tüketicinizin boş bir
Q üzerinde S4 adım numarasını nasıl yürütebileceğini göstereceğim.
Başlangıç olarak, diyelim ki programımızda ya da sürecimizde 381
ve üçüncüsünü tüketici eğilimine sokmak zorundayız, değil mi? Bu
programda herhangi bir sayıda üretici ve tüketici tehdidi olabilir.
Boşluğu açıklamak için iki tüketici tehdidi olduğunu düşünelim, değil
mi? Ve tabii ki, bu bir üretici tehdidi.
Şimdi, trad tüketicisinin çarpıklıktan bir veri öğesi tüketmek istediğini,
bu nedenle tüketici eğiliminin bir numaralı adımı gerçekleştirdiğini varsayalım.
Kuyruğu boş bulur.
Bu nedenle, tüketici tehdidi üçüncü adımda bir blok olacaktır.
Doğru.
Yani tüketici tehdidi sözde kodunu bir bağlamında tartışıyoruz ve
S3 adımında bloke olan tehdittir, değil mi? Şimdi, tehdit
üç numaralı adımda bile engellendiğinden, şimdi, üretici iş parçacığınızın
CPU'yu doğru aldığını ve altı numaralı adımı yürütmeye başladığını
ve kuyruğun kapasitesine kadar dolu olmadığını bulduğunu varsayalım.
Bu nedenle bir veri öğesi oluşturur.
Ve veri öğesini oluşturduktan sonra, bu öğeyi bu kuyruğa yerleştirir.
Değil mi? Öyleyse bu kutuyu üretici iş parçacığı tarafından kuyrukta
bulunan bir veri öğesi olarak temsil edelim ve ardından
şu anda zaten engellenmiş olan 3D'ye bir sinyal gönderildiği
için sekiz numaralı adımı yürüten bir iş parçacığı üretelim.
Bu sinyal üzücü olur olmaz, anlaşma blog durumundan yürütmeye hazır duruma geçer.
Doğru.
Ancak 31, üretici Ted muteksi serbest bırakana kadar çalıştırılmayacaktır, bu nedenle
32'nin dün gece adım numarasını çalıştırarak bu saldırıları gerçekleştirdiğini varsayalım.
Tamam mı? Şimdi üretici S9 adımının yürütülmesini
bitirmeye çalıştığı anda sorun ortaya çıkıyor.
Şimdi süreçte 31 ve 33 numaralı iki iş parçacığı daha
var ve bunlar yürütülmek üzere CPO'ya tahsis edilebilir, değil mi?
Her iki tehdit de Stephen A. üç CPU tarafından yürütülebilir.
Şu anda sorun, CPU'nun 31 yerine 333'ü kullanması durumunda ortaya çıkacaktır.
Doğru.
Dolayısıyla, çekirdek zamanlama politikasına veya tehdit zamanlama politikasına göre CPU
tarafından hangi iş parçacığının zamanlanacağı üzerinde bir kontrolünüz yoktur.
İşletim sisteminiz CPU üzerinde yürütülecek iş parçacıklarından herhangi birini seçebilir.
Doğru.
Ve bu durumda, Stephen A.'yı çeken şey, üçünün yürütülmeye hazır olmasıdır, değil mi?
Şimdi, albay olduklarını varsayalım, işletim sistemimiz yürütmek için 33'ü seçer, değil mi? Ve
333'ün bir tüketici tehdidi olduğunu zaten biliyoruz, bu yüzden şimdilik SE numaralı durakta,
94, bunun dokuz numaralı adımdan sonra yürütülen bir adım olduğu anlamına gelir.
Ama adım numarasından önce.
Doğru mu? Diyelim ki programınızın bu noktasında, fiyatların
üçü olan başka bir tüketici eğilimi kuyruğu tekrar
boşaltıyor, değil mi? Unutmayın, kuyrukta bir eleman var
ve kuyruğun bu belirli elemanını tüketen tüketici
33'tür ve kuyruk tekrar boş duruma getirilir.
Dolayısıyla, 383 numaralı üye, 382 dokuz numaralı adımı tamamladığında ve çekici bire CPU
tahsis edilmediğinde bu eylemi gerçekleştirir, yani 31'e herhangi bir zamanda CPU tahsis edilebilir.
Ancak öyle oldu ki işletim sisteminiz çalıştırmak için 31 yerine başka bir 33 seçti.
Yani 31 henüz infaz edilmedi.
Adım numarası dörttür.
Şimdi, üç numaralı tehdit gerçekleştikten sonra, adım numarası 94'tür.
Şimdi 31'in CPU'yu aldığını ve S4 adım numarasını yürüttüğünü varsayalım.
Değil mi? Şimdi 381 numaralı tüketicimizin
boş bir kuyruk tükettiğini görebilirsiniz, bu
da sorunumuza göre istenmeyen bir durumdur.
İfade veya hedef düpedüz S4 numaralı adımın boş bir kuyrukta
yürütülmesiyle sonuçlanır ki bu da varsayımımıza göre problemin durumudur.
Doğru.
Şimdi, tüketici ticaretinin boş bir kuyrukta dört
numaralı adımı engellediği çözüm düşüncemizi uygulamamız gerekiyor.
Dolayısıyla bu sorun, tüketici eğiliminin sözde kodunda yapabileceğiniz
çok küçük bir akor değişikliği ile basitçe çözülebilir.
Çözüm çok basit ve anlaşılırdır.
Sinyali aldıktan sonra uyanan tüketici iş parçacığı, kuyruğu gerçekten işlemeden önce
yüklem koşulunu tekrar kontrol etmelidir, değil mi? Yani bu basitçe, tüketici
işlem bu sinyali aldığında ve tüketici işlem gerçekten yürütmeye başladığında, S4
adımını gerçekleştirmek için bu yüklem koşulunu tekrar sürüklemesi gerektiği anlamına gelir.
Yani burada yapabileceğiniz basit bir küçük akor değişikliği, if
koşulu yerine while koşulunu yazmanız gerektiği anlamına gelir.
İşte bu kadar.
Tüketici bloktan Steed'e her yürütmeye başladığında,
yüklem koşulunu tekrar kontrol edecektir.
Ve eğer küpü boş bulursa, çünkü 31 işlem yapmadan önce başka bir tüketici iş
parçacığı küp üzerinde işlem yapmışsa, o zaman 31 koşul değişkeni üzerinde tekrar bloke olur.
Bu da basitçe, antlaşmanın boş bir kuyrukta asla Adım S4'ü yürütemeyeceği anlamına gelir.
Şimdi S2 adımındaki tüketici iş parçacığı sözde kodunda, eğer bunu wild deyimiyle
değiştirirseniz, tüketici tehdidi ve koşul değişkeninde iki parçayı senkronize etmeniz gereken
tüm çok iş parçacıklı programlar için mükemmel bir sözde kod olur.
Üretici ve tüketici iş parçacığı için tamamen aynı sözde kodu yazmalısınız, değil mi?
Şimdi bir sonraki slaytta ilerleyerek, bunun tüketici gururu için mükemmel bir sözde kod
olduğunu ve sağ tarafta da üretici iş parçacığı için mükemmel bir sözde kod
olduğunu görebilirsiniz, değil mi? Yani bunlar, uygulamanın problem ifadesi itibariyle genel sözde kodlardır.
Tabii ki, buraya bir yüklemi temsil eden bir fonksiyon
yazmanız gerekiyor, değil mi? Ve burada Vaikka üzerinde kritik
bölümün yürütülmesini temsil eden uygulamaya özel bir iş yapmanız
gerekir, değil mi? Yani bu fonksiyon, yeni tüketici iş
parçacığı uyandığında çalıştırılacak uygulamanızın kritik bölümünü temsil eder.
Yani bu genel sözde koddur ve iş parçacığı,
senkronizasyon sorunu ve çözümü kodlarken aynı modeli izleyin.
Bu, tutarlı ve somut olan üretici ve
tüketici iş parçacıkları arasındaki senkronizasyon türüdür.
Çoğu iş parçacığı senkronizasyon problemi standart üretici ve tüketici
problemlerine ayrıştırılabilir, değil mi? Bir kerede iş parçacığı
senkronizasyonu yazarken, bu sözde kodları tekrar tekrar yazacağınızı
fark edeceksiniz, çünkü çoğu iş parçacığı senkronizasyon problemi
günün sonunda minimum boyutta üretici tüketici problemlerine ayrıştırılabilir.
Dolayısıyla, iki iş parçacığını senkronize etmeniz gerektiğinde ve bu iki iş parçacığı
aslında aynı kaynak için rekabet ettiğinde ve iş parçacıkları üretici tüketici iş
parçacıkları olarak sınıflandırılabilecek nitelikte olduğunda, aklınızda ikinci bir düşünce olmadan, bu iki
sözde kodu kullanarak iki iş parçacığını senkronize etmeyi düşünmelisiniz, değil mi?