Şimdi temizlik işleyicileriyle ilgili hatırlanması gereken bazı noktaları tartışalım.
Bu nedenle, push'un derleme zamanında parantez açma ve bazı ara kodlarla değiştirildiğini düşünün.
Sol tarafta, bir iş parçacığı bağlamında çalışacak bir iş parçacığı işlevimiz olduğunu görebilirsiniz.
Ve bir geliştirici olarak bu fonksiyona iş parçacığı temizleme, push API, çağrısı eklediğinizi varsayalım.
Değil mi?
Bu nedenle, p thread cleanup push işlevinin aslında bir işlev olmadığını, derleme sırasında bazı kodlara genişleyen
bir makro olduğunu unutmayın.
Doğru.
Bu nedenle, p thread cleanup push makrosunun açılış parantezlerine ve ardından derleyici tarafından eklenen bazı kodlara genişleyeceğini
hayal etmeye çalışın.
Doğru.
Benzer şekilde, iş parçacığı işlevinize p thread cleanup push API'sine iki çağrı eklerseniz, bu, kodunuza iki
açık küme parantezinin ekleneceği ve ardından derleyici tarafından eklenen ve iş parçacığı temizleme
rutini yığınının yönetiminden sorumlu olan başka bir kodun ekleneceği anlamına gelir.
Benzer şekilde, derleme zamanında pop'un yerini bazı ara kodların ve ardından kapama parantezlerinin alacağını hayal
etmeye çalışın.
Doğru.
Yani sol tarafta, bir programcı olarak derleme zamanında thread fonksiyonuna açılır API çağrısı eklerseniz,
bu çağrı derleyici tarafından oluşturulan bazı kodlarla değiştirilecek ve ardından parantezler
açılacaktır.
Doğru.
Artık programınızda dengesiz parantezler varsa, programınızın derlenmeyeceğini
zaten biliyorsunuz.
Benzer şekilde, programınızda push ve pop API'lerine dengesiz çağrılar varsa, programınız yine derlenmeyecek
ve programınızda dengesiz parantezler olmasıyla aynı hatayı verecektir.
Doğru.
Demo amacıyla, fonksiyonumuzdan pop çağrılarından birini kaldırdığımı varsayalım.
Değil mi?
Şimdi bu fonksiyonu derlemeye çalışırsanız, aynı hatayı alırsınız, değil mi?
Girdinin sonunda beklenen bildirim veya ifade.
Bu hata, programınızda dengesiz parantezler olduğunda ortaya çıkar.
Bu temizleme, pop ve temizleme itme API'lerinin, açma veya küme parantezleri ve ardından bazı kodlarla genişleyen makrolar
olduğunu unutmayın.
Doğru.
O zaman temizleme işleyicileri hakkında hatırlanması gereken bazı noktaları hızlıca tartışalım.
Bu nedenle, push'u açılış parantezleri ve pop'u kapanış parantezleri olarak hayal ederek programınızda her zaman parantezlerin
dengeli olduğundan emin olun.
Doğru.
Ve pthread cleanup pop API'sinde.
Eğer argüman olarak sıfır geçerseniz, bu sadece bu API'ye yapılan çağrının yığının tepesinden bir fonksiyonu
kaldıracağı anlamına gelir.
Yığın dediğimde, iş parçacığı temizleme yığını kastedilmektedir.
Benzer şekilde, thread cleanup pop API'sine sıfır dışında herhangi bir değer geçerseniz, bu API'ye yapılan çağrı
yalnızca temizleme rutinini yığının en üstünden çıkarmakla kalmaz, aynı zamanda bu rutini de çağırır.
Doğru.
Böylece, bu cleanup pop API'sine argüman olarak sıfır değerini geçmek ile bu cleanup pop API'sine argüman olarak sıfır olmayan
bir değer geçirmek arasındaki farkı fark edebilirsiniz.
Doğru.
İş parçacığı p thread exit kullanılarak sonlandırıldığında temizleme işlevleri de çağrılır.
Doğru.
Dolayısıyla, işleviniz basitçe p thread exit kullanarak sonlandırılırsa, bir iş parçacığının
temizleme yığınında bulunan tüm temizleme işleyicileri çağrılacak ve sonunda yığından kaldırılacaktır.
Bu nedenle, temizleme işleyici işlevleriniz herhangi bir nedenle çağrıldığında, diyelim ki iş parçacığınız
iptal sinyali aldı veya iş parçacığınız p iş parçacığı çıkış çağrısı kullanılarak sonlandırıldı.
Ayrıca yığından da çıkarılırlar.
İş parçacığı temizleyici işlevlerinizin çağrılması ancak yığından kaldırılmaması söz konusu değildir.
Çağrılırlarsa, iş parçacığının temizleme yığınından da kaldırılırlar.
Ve son olarak, iş parçacığının yığınında bulunan temizleme işlevleri, iş parçacığı basit bir return deyimi sayesinde
sonlandırıldığında çağrılmaz.
Bu kadar basit.
Doğru.
Aynı örneğimize gelirsek, bu, dosyaya yazan bir iş parçacığı bağlamında çalışan
işlevdir.
Şimdi, diyelim ki fonksiyonumu on kez çalıştırmak istiyor olabilirim, değil mi?
Yani buraya basitçe int is equal to ten yazacağım ve diyelim ki A is less than equal to ten koşulunu
yazacağım, değil mi?
Ve basitçe A'nın değerini bir artıracağım.
Yani while döngüm şimdi on kez yinelenecek.
Bunu, iş parçacığı işlevimin sonsuz bir döngü içinde çalışmaması ve sonunda iş parçacığı
işlevimin iptal sinyalini almadan bu temizleme pop API'lerini doğru şekilde çağırması için yaptım.
Doğru.
Şimdi bu işlev iş parçacığım tarafından çağrıldığında, bu while döngüsü on yinelemeden sonra sona erdiğinden,
yine de temizleme işleyicilerimi çağırmak istiyorum çünkü belleği boşaltmak ve bu dosyayı kapatmak
istiyorum.
Değil mi?
Bu durumda, bu API'lere argüman olarak sıfır olmayan bir değer iletirim.
Değil mi?
Bu pop API'ye sıfır olmayan bir argüman ilettiğinizde, bu pop API yalnızca temizleme yığınından bir temizleme işleyicisini
kaldırmakla kalmaz, aynı zamanda bu işleyicileri de çağırır.
Burada dikkat edilmesi gereken bir diğer husus da, diyelim ki dosyanızın açılması başarısız oldu, değil mi?
Yani f open bana bir null pointer döndürecek demektir.
Yani bu, bu koşulun doğru olacağı ve fonksiyonumdan geri dönmeye çalışacağım anlamına geliyor.
Şimdi, normal return deyimini kullanarak fonksiyonumdan döndüğümde temizleme işleyicilerinin çağrılmadığını
hatırlayın.
Bu basitçe, bu belleği serbest bırakamayacağım anlamına geliyor.
Doğru.
Bu nedenle, işlevinizden her döndüğünüzde basit return deyimi yerine genellikle p thread alt çizgi exit
çağrısını kullanmaya dikkat edin.
Doğru.
Çünkü p iş parçacığı çıkışının çağrılması temizleme işleyicilerini çağıracak ve temizleme işleyicileri
iş parçacığınız tarafından işgal edilen tüm kaynakları serbest bırakmaya özen gösterecektir.
Değil mi?
Bu nedenle, iptal edilebilen bir iş parçacığı uyguluyorsanız, normal return deyimini kullanmak yerine
p thread exit kullanarak iş parçacığınızdan dönmek daha mantıklıdır.
Doğru.
Ve daha önce de açıkladığım gibi, p iş parçacığı çıkışı, iş parçacığınız tarafından tahsis edilen kaynakları temizleyecek
olan temizleme işleyicilerini çağıracak ve basit bir return deyimi kullanarak size kaynak sızıntısı
sorunu verecektir.
Doğru.
Başka bir yol da P thread exit zero kullanarak goto deyimini kullanabilir ve clean up işleyicilerine
git diyebilirsiniz, clean up'ı bir etiket olarak kullanabilir ve sonunda bu etiketi tanımlayabilirsiniz, değil
mi?
Yani bu aynı şey, değil mi?
Bu da aynı şeyi başarmanıza yardımcı olacaktır.
Sonuç olarak, iş parçacığından her döndüğünüzde, iş parçacığınız tarafından tahsis edilen veya işgal edilen
kaynakları serbest bıraktığınıza dikkat edin, doğru, bunu ne şekilde başarmak isterseniz.