Sinyal Yakalama ve Gönderme
Sinyal Yakalama
Uygulama tarafından yakalanabilmesine izin verilen sinyaller, ilgili fonksiyonlar kullanılarak uygulama içerisinde yakalanıp işlenecek hale getirilir. Bunun için temel olarak, yakalamak istediğimiz sinyalleri belirlemek ve bu sinyalleri işleyecek callback fonksiyonlarını hazırlamamız gerekir.
Sinyal işleme sürecinde aynı callback fonksiyonunu birden fazla sinyal için kullanmamız da mümkündür. Asenkron olarak çağırılacak callback fonksiyonunun prototipi aşağıdaki gibidir:
Parametre olarak gelen int
değeri, sinyalin numarasını gösterecektir.
Yakalamak istediğimiz sinyal ve karşılayacak callback fonksiyonunu belirtmek için signal
veya sigaction
fonksiyonları kullanılır. Kullanım prototipleri aşağıdaki gibidir:
signal
kullanımı artık önerilmemektedir, bunun yerine daha fazla kontrol sunan sigaction
kullanımı tercih edilmelidir. Zaten günümüzde glibc içerisindeki signal gerçekleştirimi de sigaction fonksiyonunu sarmalayan bir yapıdan ibarettir.
Aşağıdaki örnek uygulamayı sample.c
adında kaydediniz.
Sonrasında aşağıdaki gibi derleme işlemini yapıp çalıştıralım:
Uygulamayı çalıştırdıktan sonra CTRL-C tuş kombinasyonu ile INT sinyali ürettiğimizde sigaction
ile belirttiğimiz callback fonksiyonumuzun devreye girdiğini, TERM sinyali dışında bir sinyal geldiği için uyarı mesajı verip çalışmasına devam ettiğini görmekteyiz.
Başka bir konsoldan uygulamamıza kill
komutu ile TERM sinyalini gönderdiğimizde ise beklediğimiz gibi exit_flag
değişkeninin değerinin 1 yapılmak suretiyle sonlandığını görmekteyiz. Bu şekilde uygulama sonlandığında çıkış değerinin de $? kabuk değişkeninde beklediğimiz üzere 0 olduğunu görüyoruz:
Bu noktada şu soruyu kendimize soralım: Test uygulamamız çalışıyorken diğer konsoldan uygulama içerisinde işlediğimiz TERM ve INT sinyalleri dışında, örneğin USR2 sinyalini gönderirsek ne olur?
Yukarıda görüldüğü üzere, uygulamamız USR1 sinyalini aldığında, User defined signal 2 mesajıyla sonlandı. Bu bizim uygulama içerisinden bastırdığımız bir mesaj değil. Ayrıca uygulamanın çıkış değeri önceki örnekte olduğu gibi 0 değil, 140 oldu.
Uygulamada nasıl işleneceği düzenlenmiş olmayan bir sinyal geldiğinde, ilgili sinyalin önceki bölümde vermiş olduğumuz tabloda yer alan öntanımlı eylemi gerçekleşir. SIGUSR2 sinyalinin öntanımlı eylemi de uygulamayı durdurmak olduğu için uygulamamız sonlandı. Eğer öntanımlı eylemi yoksay şeklinde olan örneğin SIGURG sinyalini göndermiş olsaydık, uygulamamız çalışmasına bir şey olmamış gibi devam edecekti:
Bu bilgiler ışığında, uygulamalarımızda sinyallere karşı önlem almadığımızda, beklenmeyen bir sinyalin bize ulaşması nedeniyle kontrolsüz sonlanmalara yol açacağını rahatlıkla söyleyebiliriz.
Sinyal Gönderme
Uygulama içerisinden sinyal göndermek için prototipi aşağıda belirtilen kill
fonksiyonu kullanılır:
Fonksiyon basitçe parametre olarak verilmiş olan PID değerine sahip uygulamaya istenen sinyalin gönderimini sağlamaktadır. İşlemin gerçekleşebilmesi için ilgili uygulamaya sinyal gönderebilme yetkisinin olması gerekir. Örnek olarak A kullanıcısı B kullanıcısının uygulamalarına sinyal gönderemez, ancak kendi sahip olduğu uygulamalara sinyal gönderebilir.
Sistemdeki root kullanıcısı veya Linux Capabilities API üzerinden CAP_KILL kabiliyetine sahip olan uygulamalar ise herhangi bir uygulamaya sinyal gönderebilirler.
Uygulama dışından genel amaçlı sinyal gönderme işlemleri için kill komutunu kullanabilirsiniz.
Uygulama içerisinden bir başka uygulama yerine, çalışan uygulamanın kendisine sinyal gönderilmek istendiğinde raise
ve abort
fonksiyonları kullanılır.
Last updated
Was this helpful?