Evreler ve Çatallaşmak
Önceki POSIX Evreleri Sonraki
Evreler ve Çatallaşmak
Bir çok evreli POSIX süreci fork işlevinin çağırdığında ne olması gerektiği kesin değildir. Çatallaşma sırasında doğru çalışan ancak fork işlevini kullanmayan kodlar yazmanız gerekebilir. fork ve pthread_once gibi bazı kütüphane oluşumları ile standart G/Ç akımları arasındaki etkileşime dikkat etmelisiniz.
fork süreçteki bir evre tarafından çağrıldığında, çağıran sürecin bir kopyası olan yeni bir süreç oluşturur. Belirli sistem nesnelerinin kopyalanmasına ek olarak, üst sürecin bellek alanlarının anlık görünümünü alır ve alt süreçte özdeş alanlar oluşturur. Olayı biraz daha karmaşıklaştırmak için, iki veya daha fazla evre kendi içlerinde de çatallaşarak iki veya daha fazla alt süreç oluşturabilirler.
Alt süreç üst sürecinin adres alanının bir kopyasına sahiptir, fakat evrelerinden hiçbirini miras almaz. Alt sürecin işletilmesi fork işlevinden 0 değeriyle dönen bir evre ile sağlanır; öyle ki bu alt süreçteki tek evredir. Çatallaşma sırasında evreler miras alınmadığı için bazı sorunlar ortaya çıkar. fork'un çağrılması sırasında, üst süreçteki fork'u çağıran evre dışındaki evreler kodun kritik bölgelerini işletiyor olabilirler. Sonuç olarak, alt süreç iyi tanımlanmış durumda olmayan nesnelerin kopyasını alabilir. Bu potansiyel sorun yazılımın bütün bileşenlerini etkiler.
Alt süreçte kullanılmaya devam edecek herhangi bir yazılım bileşeni fork süresince durumunu doğru bir şekilde ele almalıdır. Bu amaçla, POSIX arayüzü özel bir işlev olan pthread_atfork'u, fork içinden çağrılan işleyici işlevlere göstericiler kurmak için sağlar.
int pthread_atfork
(void (*hazırla)(void),
 void (*üstsüreç)(void),
 void (*altsüreç)(void))
işlev
pthread_atfork işlevi fork ile yeni bir süreç oluşturmadan hemen önce ve oluşturulduktan hemen sonra çağrılan işleyici işlevleri kaydeder. hazırla işleyicisi yeni bir süreç oluşturulmadan önce üst süreçten çağrılacaktır. üstsüreç işleyicisi fork dönmeden az önce üst süreçten çağrılacaktır. altsüreç işleyicisi fork dönmeden az önce alt süreçten çağrılacaktır.
pthread_atfork başarı halinde 0, hata halinde sıfırdan farklı bir hata kodu döndürür.
hazırla, üstsüreç ve altsüreç işleyicilerinden bir veya daha fazlası NULL olarak verilebilirler, bu o noktada bir işleyiciye ihtiyaç olmadığı anlamına gelir.
pthread_atfork birçok işleyici kümesi kurmak için birçok kez çağrılabilir. fork anında, üstsüreç ve altsüreç işleyicileri FIFO sırasıyla çağrılırken (ilk eklenen, ilk çağrılır), hazırla işleyicileri LIFO sırasında çağrılırlar (pthread_atfork ile son eklenen, fork'tan önce ilk çağrılır).
Eğer bu işleyicileri kaydetmek için yeterli bellek mevcut değilse, pthread_atfork başarısız olur ve ENOMEM döndürür. Aksi takdirde 0 döndürür.
fork ve pthread_atfork işlevlerine işleyiciler bağlamında çok katılışlı işlev gözüyle bakılmamalıdır. Eğer fork içinden çağrılan pthread_atfork işleyicisi pthread_atfork veya fork çağırırsa, davranışı bilinemez.
Çatallaşmada üçlü işleyicilerin kaydı atomik bir işlemdir. Eğer çatallaşma ile aynı zamanda yeni işleyiciler kaydedildiyse ya her üç işleyici de çağrılacaktır ya da hiçbiri.
İşleyiciler alt süreçler tarafından miras alınır ve exec ile yeni bir süreç görüntüsü yüklemekten başka onları kaldırmanın hiçbir yolu yoktur.
pthread_atfork'un amacını anlamak için, fork'un geçerli kilit durumlarıyla muteksler dahil bütün bellek alanının kopyasını çıkardığını hatırlayınız, fakat sadece çağıran evreyi: diğer evreler alt süreçte çalışmıyordu. fork'tan sonra muteksler kullanılamaz ve alt süreçte pthread_mutex_init ile tekrar hazırlanmaları gerekir. Bu geçerli gerçeklemenin bir kısıtıdır ve gelecek sürümlerde olabilir de olmayabilir de.
Bundan kaçınmak için, pthread_atfork ile şu şekilde işleyiciler kurun: hazırla işleyicisi muteksleri kilitler (sırayla) ve üstsüreç işleyicisi muteks kilitlerini açar. altsüreç işleyicisi muteksleri ve koşul değişkenleri gibi diğer eşzamanlama nesnelerini pthread_mutex_init kullanarak sıfırlamalıdır.
Çatallaşmadan önce global mutekslerin kilitlenmesi, bu mutekslerce korunan diğer bütün evrelerin kodun kritik bölgesindeki kilitlerinden kurtulduğundan emin olunmasını sağlar. Bu nedenle ne zaman fork üst sürecin adres alanının anlık görüntüsünü alsa, o görüntü geçerli, tutarlı veri içerir. Alt süreçteki eşzamanlama nesnelerinin sıfırlanması, üst sürecin evrelenme alt sistemindeki yapıların temizlendiğini temin eder. Örneğin, bir muteks, kilit için bekleyen bir evre bekleme sırası miras almıştır; bu bekleme sırası alt süreçte bir şey ifade etmez. Muteksin ilklendirilmesi buna dikkat ister.
Önceki Üst Ana Başlık Sonraki
Evreler ve Sinyal İşleme Başlangıç Akımlar ve Çatallaşma
Bir Linux Kitaplığı Sayfası