Sinyallerle Kesilen İlkeller
Önceki XXIV. Oylum - Sinyal İşleme Sonraki
Sinyallerle Kesilen İlkeller
open veya read benzeri bir G/Ç ilkeli bir G/Ç aygıtını beklerken bir sinyal alabilir ve bu sinyal işleme sokulabilir. Sinyalin eylemcisi işlemlerini bitirdikten sonra sistem bir sorunla başbaşa kalır: şimdi ne olacak?
POSIX bir yaklaşım belirtir: bir ilkel başarısız olduğunda ne yapacaksan beklemeden yap. Bu çeşit başarısızlıklar için hata kodu EINTR'dir. Genellikle, sinyal eylemciler kullanılan POSIX uygulamaları bu hatayı döndüren her işlev çağrısının dönüş durumuna mutlaka bakmalıdır. Çoğunlukla yazılımcılar bu genel hata kaynağına bakmayı unuturlar.
GNU kütüphanesi, geçici bir başarısızlığın ardından çağrının yinelenmesini sağlayan oldukça kullanışlı bir yöntem olan TEMP_FAILURE_RETRY makrosunu içerir:
TEMP_FAILURE_RETRY
(ifade)
makro
Bu makro ifade'yi bir kere değerlendirir ve long int türünde döner. Eğer değer -1 ise bu bir başarısızlık gösterir ve errno değişkenine hata durumu atanır. Eğer başarısız olursa ve EINTR hata kodunu raporlarsa, TEMP_FAILURE_RETRY onu tekrar değerlendirmeye tabi tutar ve bu işlem geçici başarısızlık durumu ortadan kalkana dek yinelenir.
TEMP_FAILURE_RETRY makrosunun dönüş değeri ifade'nin dönüş değeri neyse odur.
BSD, EINTR hata kodunu hiç göstermez ve daha iyi bir yaklaşım yapar: kesintiye uğratılan ilkeli başarısız olarak döndürmez ve hep yeniden başlatır. Bu yaklaşımı benimserseniz EINTR ile ilgilenmeniz gerekmez.
GNU kütüphanesindeki yaklaşımı seçebilirsiniz. Bir sinyal yakalayıcıyı sigaction ile kuruyorsanız, eylemcinin nasıl davranacağını belirtebilirsiniz. SA_RESTART seçeneğini belirtirseniz eylemci döndükten sonra ilkel kaldığı yerden işine devam eder, belirtmezseniz eylemci EINTR hatasının dönmesine sebep olacaktır. Bkz. sigaction Seçenekleri.
Seçiminizi belirtmenin diğer bir yolu da siginterrupt işlevidir. Bkz. BSD Eylemciler.
Bir sinyal yakalayıcının ne yapacağını sigaction veya siginterrupt ile belirtmezseniz, öntanımlı seçim kullanılır. GNU kütüphanesinde öntanımlı seçim sizin tanımladığınız sınama makrolarına bağlıdır. signal işlevini çağırmadan önce _BSD_SOURCE veya _GNU_SOURCE makrosunu tanımlarsanız, öntanımlı davranış ilkelin işlemi kaldığı yerden devam ettirmesidir; aksi takdirde, öntanımlı davranış EINTR ile başarısızlık olacaktır. (Kütüphane signal işlevinin diğer sürümlerini de içerir ve özellik sınama makroları gerçekte hangisinin kullanılacağının saptanmasını sağlar.) Bkz. Özellik Sınama Makroları.
Bu kısımda bahsedilen her ilkel, hata kodu olarak EINTR döndürebilen ilkellerden biridir.
Seçimizden etkilenmeyen ve işlemin kaldığı yerden devamına konu olmayan tek bir durum vardır: read veya write gibi bir veri aktarım işlevi verinin bir parçasını aktardıktan sonra bir sinyal aldığında. Bu durumda işlev zaten, kısmi başarıyı belirtmek üzere aktarılan baytların sayısı ile dönecektir.
Bunun en başta kayıt yönlenimli aygıtlarda (datagram soketleri gibi; bkz. Datagram Soket İşlemleri) beklenmeyen davranışlara sebep olduğu görülür; bir read ya da write işleminin ikiye bölünmesi iki okuma ya da yazmaya sebep olur. Aslında, bir sorun yoktur, çünkü böyle aygıtlarda bir kısmi aktarım sonrası kesme oluşamaz; bunlar bir kaydın tümünü veri aktarımı bir kez başladı mı beklemeksizin tek bir seferde aktarırlar.
Önceki Üst Ana Başlık Sonraki
Atomik Veri Erişimi ve Sinyal İşleme Başlangıç Sinyallerin Üretilmesi
Bir Linux Kitaplığı Sayfası