Evet arkadaşlar, şimdi mutekslerin kullanımını göstereceğimiz bir örneği tartışalım.
Bu örneğin amacı, bir sürecin ortak bir veri yapısı üzerinde çakışan işlemler gerçekleştiren iki
iş parçacığı arasında karşılıklı dışlamayı uygulamaz veya sağlamazsanız, programımız tarafından üretilecek
tanımlanmamış davranışa tanık olacağız.
Doğru.
Ve sonra muteksleri kullanarak bu tanımlanmamış davranış sorununu çözeceğiz.
Dolayısıyla, tartışacağımız kod örneği bu konumda bulunabilir.
Şimdi de tartışacağımız problem cümlesini ele alalım.
Dolayısıyla, bu büyük harf D ile temsil edilen ortak bir veri yapısına sahip olduğumuz bir P sürecimiz olacak
Şimdi bu veri yapısı herhangi bir şey olabilir, ancak basitlik adına, D veri yapısını
1'den 5'e kadar beş öğe içeren bir dizi olarak temsil ediyoruz, değil mi?
Bu yüzden çok basit bir veri yapısını ele aldım, ancak gerçekte bu veri yapısı herhangi bir veri yapısı olabilir.
Bu bir bağlantı listesi, bir ağaç ya da karmaşık veri yapılarından oluşan bir koleksiyon olabilir.
Yapacağım şey, programımızda bir T1 iş parçacığı oluşturmak ve bu T1 iş parçacığının
şu anda bu dizide bulunan D veri yapısı üzerinde okuma işlemi gerçekleştirmesidir.
Bu okuma işlemi nedir?
Bu okuma işlemi hiçbir şey değildir, ancak sadece bu dizinin elemanlarının toplamını hesaplar ve
doğru şekilde yazdırır.
Ve bu T1 iş parçacığının bu dizi üzerinde sonsuz bir döngü içinde bu okuma işlemini gerçekleştireceğini
unutmayın.
Doğru.
Yaptığım şey, bu dizi üzerinde yineleme yapacak, bu dizinin öğelerinin toplamını hesaplayacak
ve toplamı yazdıracak bir iş parçacığı oluşturmak ve bu görevi sonsuza kadar yapmaya devam
etmektir.
Değil mi?
Benzer şekilde, bu dizi üzerinde yazma işlemi gerçekleştirecek başka bir t iki iş parçacığı oluşturacağım.
Doğru.
Peki bu yazma işlemi nedir?
Bu yazma işlemi çok basittir.
t iki iş parçacığı bu dizinin ilk ve son elemanlarını değiştirecek ve bunu sonsuz
bir döngü içinde yapacaktır.
Buradaki amaç, iki iş parçacığı oluşturacak olmamızdır.
Bir iş parçacığı bir okuyucu iş parçacığı ve diğer iş parçacığı bir yazar iş parçacığıdır ve her iki iş
parçacığı da eylemlerini uygulama yazma iş parçacığının ortak veri yapısı üzerinde gerçekleştirecektir.
T bir okuma işlemi gerçekleştirirken, t iki iş parçacığı yazma işlemi gerçekleştiriyor ve okuma yazma
işlemlerinin çakışan işlemler olduğunu zaten biliyoruz.
Şimdi size çok basit bir soru sorarsam, bu programı tam burada çalıştırdığımda bu programın çıktısı nedir diye
sorarsam, thread t one'ın dizinin elemanlarının toplamını yazdırdığını görebilirsiniz ve bu
programın çıktısını oluşturan şey budur.
Sorum şu ki, eğer böyle bir program yazıp çalıştırırsanız bu programın çıktısı
ne olacak?
Dolayısıyla, bu programı gerçekten derlemeden ve çalıştırıp çıktısını görmeden önce, burada
anlattığım gibi basit bir problem cümlesi yazmanızı ve bu programın olası çıktısının ne olduğunu belirlemenizi
tavsiye ederim.
Evet arkadaşlar, şimdi örnek kodu görelim.
Dolayısıyla, aşağıdaki dizinde bulabileceğiniz örnek bir kod, thread basics slash mutex'tir.
Örnek.
Bu dizinde mutex example c kaynak dosyasını bulacaksınız, yani bu dosya az önce tartıştığımız problem
ifadesinin aynısını uygular.
Şimdi bu dosyadaki kaynak kodunu hızlıca tartışalım çünkü kaynak kodu çok basit.
Yani bu dosyada yaptığım şey, öncelikle beş eleman içeren bir dizi
almak ve bu işlemin bu dosyasının global bir dizisidir.
Değil mi?
Daha sonra ana işleve geçerseniz, ana işlevde yaptığım şey iki iş parçacığı oluşturmaktır.
İlk iş parçacığı, dizinin elemanlarının toplamını sonsuz bir döngü içinde hesaplayan iş parçacığıdır.
Ve ikinci iş parçacığı sadece dizinin ilk ve son öğesini değiştirir, değil mi?
Yukarıda bu iki fonksiyonun uygulamasını görebilirsiniz.
Bu, bir iş parçacığı oluşturduğumuz toplam iş parçacığı oluşturma işlemidir.
Bu da sorumluluğu sadece dizinin ilk ve son elemanını değiştirmek olan başka bir iş parçacığı yaratan başka
bir işlevdir.
Değil mi?
Dolayısıyla, bu geri arama işlevlerinin uygulanmasına bakarsanız, uygulamanın oldukça basit olduğunu
görebilirsiniz.
Basitçe dizi üzerinde yineleme yapar ve dizinin toplamını yazdırırsınız ve bunu sonsuz bir döngü içinde yapmaya devam
edersiniz, değil mi?
Benzer şekilde, başka bir iş parçacığında dizinin ilk ve son elemanını değiştiriyoruz.
Değil mi?
Ve yine, bu alıştırmayı sonsuz bir döngü içinde yapıyoruz.
Şimdi bunu söyledikten sonra, artık oldukça basit olan bu programın uygulanmasının farkındasınız.
Şimdi bu programı derler ve çalıştırırsanız, ortaya çıkan bariz soru, bu programın çıktısının ne
olduğudur?
Programın çıktısı, bu dosyada bulunan tek print of ifadesinden gelir.
Bu tek print of deyimidir ve bu nedenle çıktı, dizinin elemanlarının toplamını hesaplayan iş
parçacığı tarafından hesaplanan olası toplamı oluşturur.
Değil mi?
Yani beklenti, bu diziye göre beklenen toplamın 15 olmasıdır, değil mi?
Bakalım.
Şimdi bu programı derleyip çalıştıralım ve bu dizinin elemanlarının olası toplamının
19 olduğunu göreceksiniz.
Bir yerde saat 11.
Bir yerde 15.
Doğru.
Ve bir yerlerde 19.
Doğru.
Dolayısıyla bu program, dizinin elemanlarının toplamının üç olası değerini yazdırır.
1115 ve 19.
Doğru.
Şimdi iki farklı iş parçacığının aynı veri yapısı üzerinde hareket ettiğini anlıyorsunuz.
Bu durumda, veri yapısı sizin dizinizdir, ancak program çıktısı yanlıştır, değil mi?
Program, dizinin elemanlarının toplamını kimi zaman 19, kimi zaman 11 olarak yazdırıyor,
oysa doğru değer 15'tir.
Doğru.
Slayta geri dönecek olursak, T1 iş parçacığının dizinin elemanlarının toplamını 15, 11 ve 19
olarak yazdırdığını görebilirsiniz.
Bu üç olası değer, değil mi?
Oysa biz zaten doğru olanın 15 olduğunu biliyoruz.
Yani cevap, t1 iş parçacığının neden yanlış değerler yazdırdığıdır, çünkü t1 iş parçacığı bu veri yapısı üzerinde okuma işlemi
gerçekleştirirken aynı zamanda bu dizi t2 iş parçacığı tarafından değiştirilmektedir.
Yani bir şekilde t1 iş parçacığı bu dizinin elemanları üzerinde toplamı hesapladığında, T1 iş parçacığı aslında
bu dizinin dört olası anlık görüntüsünü görür.
İlk anlık görüntü aynıdır.
Bu, aslında orijinal dizi olan 12345'tir.
İkinci enstantane bir, iki, üç, dört ve bir.
Dolayısıyla bu anlık görüntü, T2 iş parçacığı dizi üzerinde takas işlemi gerçekleştirirken, dizinin
son elemanına birinci elemanı yazdığında, ancak bu dizinin ilk elemanına henüz beşinci elemanı
yazmadığında görünecektir.
Değil mi?
Dolayısıyla, T1 iş parçacığının dizinin ara anlık görüntüsünü gördüğü küçük bir pencere vardır.
T2 iş parçacığı aslında dizinin öğelerini değiştirme sürecindeyken ancak henüz işlemini
tamamlamamışken.
Doğru.
Yani bu dizinin elemanlarının toplamı 11 olacak, değil mi?
Benzer şekilde, T1 iş parçacığının göreceği üçüncü anlık görüntü beş, iki, üç, dört ve beş olacaktır.
Doğru.
Nedeni de aynı.
Yani bu dizinin elemanlarının toplamı 19 olacaktır.
Ve T1 iş parçacığının göreceği dördüncü anlık görüntü beş, iki, üç, dört ve bir olacaktır.
Değil mi?
Ve bu dizinin elemanlarının toplamı hala 15'tir, doğru.
Böylece, aynı dizi iş parçacığı tarafından değiştirildiği için T1 iş parçacığının aslında dizinin dört farklı anlık görüntüsünü
gördüğünü görebilirsiniz.
T2 Sağ.
Bu nedenle toplam 11, 19 ve 15 basılmaktadır.
Bir sonraki ders videosunda Mutex'leri kullanacağız ve T1 iş parçacığı dizinin elemanlarının toplamını
hesaplamak için bu diziyi okurken, T2 iş parçacığının dizinin elemanlarını güncellemesine
izin verilmemesini sağlayacağız ve tersine, T2 iş parçacığı dizinin ilk ve son elemanı üzerinde takas
yapıyorsa, bu süre içinde T1 iş parçacığının dizinin elemanlarını okumasına izin verilmeyecektir.
Değil mi?
Yani temel olarak karşılıklı dışlama uygulayacağız.
Yani, herhangi bir zamanda bu dizi üzerinde yalnızca bir iş parçacığı işlem yapacaktır.
Dolayısıyla beklentimiz, karşılıklı dışlama iş parçacığını dağıttıktan sonra, T1'in dizinin elemanlarının
toplamını 15 ve her zaman 15 olarak yazdırması olacaktır.
Doğru.