Not : Bu konu ile ilgili olarak POSIX Sinyalleri başlıklı yazıya göz atabilirsiniz.
Pending Signal Nedir ?
Eğer bir signal handler çalıştırılıyorsa aynı sinyalden 1 veya daha fazla gelse bile signal handler bir nevi bloke olduğu için tekrar çalıştırılmaz.
Yeni sinyaller için pending bayrağı kaldırılır. Bayrak bir sayaç değildir, yalnızca pending signal olduğunu belirtir. Çalışan signal handler bitince, pending bayrağı havadaysa signal handler bir kere daha çağırılır.
SIGILL (4)
Açıklaması şöyle
Bu sinyalin SIGSEGV'den farkı biraz anlamını kaybetmiş. Bence şöyle aklımda tutmayı daha uygun buldum. Eğer bir sanal adres varsa ve bu sanal adres izin verilen adres alanı dışındaysa bu hatayı alırız. Aşağıdaki örnek bu durumu gösteriyor. Dokunulmaması gereken bir alana dokunduğu için SIGBUS hatası veriyor.
SIGPIPE (13)
Pending Signal Nedir ?
Eğer bir signal handler çalıştırılıyorsa aynı sinyalden 1 veya daha fazla gelse bile signal handler bir nevi bloke olduğu için tekrar çalıştırılmaz.
Yeni sinyaller için pending bayrağı kaldırılır. Bayrak bir sayaç değildir, yalnızca pending signal olduğunu belirtir. Çalışan signal handler bitince, pending bayrağı havadaysa signal handler bir kere daha çağırılır.
SIGILL (4)
Açıklaması şöyle
SIGILL is the signal for an illegal instruction at the processor, which happens very rarely. The default action after receiving SIGILL is terminating the program and writing a core dump. The signal ID of SIGILL is 4. You encounter SIGILL very rarely, and I have absolutely no idea how to generate it in your code except via sudo kill -s 4 <pid>.C ile bu sinyali oluşturmak için şöyle yaparız.
main=6;veya şöyle yaparız.
const main=6;
SIGBUS (7)Bu sinyalin SIGSEGV'den farkı biraz anlamını kaybetmiş. Bence şöyle aklımda tutmayı daha uygun buldum. Eğer bir sanal adres varsa ve bu sanal adres izin verilen adres alanı dışındaysa bu hatayı alırız. Aşağıdaki örnek bu durumu gösteriyor. Dokunulmaması gereken bir alana dokunduğu için SIGBUS hatası veriyor.
void test(void *a)
{
asm("mov %0, %%rbp\n\t"
"mov 0(%%rbp), %%rdx\n\t"
: : "r"(a) : "rbp", "rdx");
}
int main()
{
test((void *)0x706a2e3630332d69);
return 0;
}
SIGPIPE (13)
Kapatılmış olan pipe veya sockete veri yazmaya çalışınca gönderilen sinyal. Karşıdaki uygulamanın haber vermeden kapandığını anlamamızı sağlar.
SIGTERM (15)
SIGTERM uygulamaya nazikçe artık kapanması gerektiğini söylemektir. Java - Process.destroy() source code for Linux sorusunda da anlatıldığı gibi Process.destroy() metodu çağırılınca kapatılmak istenen uygulamaya bu sinyali gönderir. Aslında Java dokümanında "The subprocess represented by this Process object is forcibly terminated." denmesine rağmen benim anladığım kadarıyla bu sinyal göz ardı edilebilir.
SIGCHLD (17)
Bir uygulama kapanırken kendisini yaratan uygulamaya SIGCHLD sinyalini de gönderir. Aşağıda bunu gösteren bir şekil var.
Buradaki soruya verilen cevapta fork/exec ile çalıştırılan bir uygulamayı beklemek için örnek kod verilmiş.
Gerçi bence bu sinyalin esas kullanım alanı yukarıdaki örnekteki gibi child uygulamanın bitmesini beklemek değil de burada söylendiği gibi arka planda çalıştırılan bir uygulamanın bittiğinin algılanması olmalı.
Burada ise aynı bir kabukta olduğu gibi arka planda çalışan uygulama bitince zombie olmaması için waitpid() metodu ile bitiş sonucunun alınması örneği var.
Eğer bir üst uygulama çalıştırdığı alt uygulamanın sonucunu beklemeden kapanırsa, alt uygulama Linux'ta init tarafından sahiplenilir.
Bir başka açıklama ise burada.
SIGSTOP ve SIGCONT (18-19)
SIGSTOP bir uygulamayı duraklatmak için SIGCONT ise devam ettirmek için kullanılır. Bu sinyaller durdurulamazlar.
SIGTTIN (21)
Controlling terminalden farklı bir gruptaki uygulama terminale okuma/yazma işlemi başlatırsa bu sinyali alır ve suspend edilir.
SIGSYS (31)
Bad system call anlamına gelir.
Sinyaller ve Stack
Burada yazdığına göre sinyaller uygulamanın stack'i içinde çalıştırılıyor. Ancak arzu edilirse ayrı bir stack tanımlamak ta mümkün. Aslında cümlede küçük bir yanlışlık var. Process'ler stack sahibi değildirler. Thread'ler bir stack'e sahiptir. Cümleyi thread stack diye okursak sorun kalmıyor.
Sinyal Set Metodları
Sinyal setini sıfırlayan ve değer atayan sigemptyset,sigfillset metodlarıdır.
sigemptyset
Bu metod verilen seti sıfırlar. Aynı memset gibi çalışır.Metodun imzası aşağıdaki gibidir.
sigfillset
sigaddset
sigdelset
sigismember
Sinyal Yakalamak için Kullanılabilecek Metodlar
signal
Sinyali default handler'ına atamak için örnek:
sigaction
sigaction yazısına taşıdım.
sa_handler alanının kullanımı
sa_handler alanına SIG_IGN değerini atayarak sinyalin dikkate alınmaması sağlanabilir. Örnek:
sa_handler alanına SIG_DFL değerini atayarak sinyalin default handler'ının çağırılması sağlanabilir.
Bu kullanım şeklinde signal handler metoduna sinyalin numarası gelir.
Örnek:
sigaction yazısına taşıdım.
Örnek:
void handler (int sig, siginfo_t * info, void * a)
{
//Kullanıcı tarafından gönderilen sinyal
if (info->si_code == SI_USER) {
}
}
struct sigaction s;
s.sa_sigsion = handler;
s.sa_flags = SA_SIGINFO;
sigemptyset (&s.sa_mask);
sigaction (SIGRTMIN, &s, NULL);
sa_mask alanının kullanımı
sigaction yazısına taşıdım.
sig_atomic_t
Aşağıda shared bir sig_atomic_t kodu örneği var.
Sinyalleri Bloke Etmek
SIG_SETMASK ilk listedeki sinyalleri bloke eder, ikinci listedekileri ise bloke edilmekten çıkarır. Eğer ikinci liste NULL verilirse önceden bloke edilmiş sinyalleri temizler ve sadece ilk listedekileri bloke eder.
Örnek:
SIGTERM (15)
SIGTERM uygulamaya nazikçe artık kapanması gerektiğini söylemektir. Java - Process.destroy() source code for Linux sorusunda da anlatıldığı gibi Process.destroy() metodu çağırılınca kapatılmak istenen uygulamaya bu sinyali gönderir. Aslında Java dokümanında "The subprocess represented by this Process object is forcibly terminated." denmesine rağmen benim anladığım kadarıyla bu sinyal göz ardı edilebilir.
SIGCHLD (17)
Bir uygulama kapanırken kendisini yaratan uygulamaya SIGCHLD sinyalini de gönderir. Aşağıda bunu gösteren bir şekil var.
Buradaki soruya verilen cevapta fork/exec ile çalıştırılan bir uygulamayı beklemek için örnek kod verilmiş.
Gerçi bence bu sinyalin esas kullanım alanı yukarıdaki örnekteki gibi child uygulamanın bitmesini beklemek değil de burada söylendiği gibi arka planda çalıştırılan bir uygulamanın bittiğinin algılanması olmalı.
Burada ise aynı bir kabukta olduğu gibi arka planda çalışan uygulama bitince zombie olmaması için waitpid() metodu ile bitiş sonucunun alınması örneği var.
Eğer bir üst uygulama çalıştırdığı alt uygulamanın sonucunu beklemeden kapanırsa, alt uygulama Linux'ta init tarafından sahiplenilir.
Bir başka açıklama ise burada.
SIGSTOP ve SIGCONT (18-19)
SIGSTOP bir uygulamayı duraklatmak için SIGCONT ise devam ettirmek için kullanılır. Bu sinyaller durdurulamazlar.
The SIGSTOP signal instructs the operating system to stop a process for later resumption.Örnek:
kill -19 `cat /var/run/mypidfile` ; kill -18 `cat /var/run/mypidfile`
SIGTTIN (21)
Controlling terminalden farklı bir gruptaki uygulama terminale okuma/yazma işlemi başlatırsa bu sinyali alır ve suspend edilir.
SIGSYS (31)
Bad system call anlamına gelir.
Sinyaller ve Stack
Burada yazdığına göre sinyaller uygulamanın stack'i içinde çalıştırılıyor. Ancak arzu edilirse ayrı bir stack tanımlamak ta mümkün. Aslında cümlede küçük bir yanlışlık var. Process'ler stack sahibi değildirler. Thread'ler bir stack'e sahiptir. Cümleyi thread stack diye okursak sorun kalmıyor.
By default, the signal handler is invoked on the normal process stack.
It is possible to arrange that the signal handler uses an alternate stack;
see sigaltstack(2) for a discussion of how to do this and when it might
be useful.
Sinyal Set Metodları
Sinyal setini sıfırlayan ve değer atayan sigemptyset,sigfillset metodlarıdır.
sigemptyset
Bu metod verilen seti sıfırlar. Aynı memset gibi çalışır.Metodun imzası aşağıdaki gibidir.
int sigemptyset(sigset_t *set);Örnek:
sigset_t ss;
sigemptyset(&ss);
sigfillset
sigaddset
sigdelset
sigismember
Sinyal Yakalamak için Kullanılabilecek Metodlar
signal
Sinyali default handler'ına atamak için örnek:
signal(SIGINT, SIG_DFL);SIG_DFL default handling demek.
sigaction
sigaction yazısına taşıdım.
sa_handler alanının kullanımı
sa_handler alanına SIG_IGN değerini atayarak sinyalin dikkate alınmaması sağlanabilir. Örnek:
//set struct action to ignore signal
struct sigaction action;
action.sa_handler=SIG_IGN;//handler set to ignore the signal
action.sa_flags=0;
//registeration
sigaction(SIGINT,&action,0);
sa_handler alanına SIG_DFL değerini atayarak sinyalin default handler'ının çağırılması sağlanabilir.
Bu kullanım şeklinde signal handler metoduna sinyalin numarası gelir.
Örnek:
void h(int sig)sa_sigaction alanının kullanımı
{
}
struct sigaction s;
s.sa_handler = h;
sigemptyset (&s.sa_mask);
s.sa_flags = SA_RESTART; //ve diğer seçenekler
int r = sigaction (SIGUSR1, &s, NULL);
sigaction yazısına taşıdım.
Örnek:
void handler (int sig, siginfo_t * info, void * a)
{
//Kullanıcı tarafından gönderilen sinyal
if (info->si_code == SI_USER) {
}
}
struct sigaction s;
s.sa_sigsion = handler;
s.sa_flags = SA_SIGINFO;
sigemptyset (&s.sa_mask);
sigaction (SIGRTMIN, &s, NULL);
sa_mask alanının kullanımı
sigaction yazısına taşıdım.
sig_atomic_t
Aşağıda shared bir sig_atomic_t kodu örneği var.
volatile sig_atomic_t interrupted=false;
...
void signal_handler(int s)
{
// ...
interrupted=true;
}
...
while (!converged && !interrupted)
{
// Perform computations
}
// Save file properly
Sinyalleri Bloke Etmek
SIG_SETMASK ilk listedeki sinyalleri bloke eder, ikinci listedekileri ise bloke edilmekten çıkarır. Eğer ikinci liste NULL verilirse önceden bloke edilmiş sinyalleri temizler ve sadece ilk listedekileri bloke eder.
Örnek:
sigset_t allSigs;
sigfillset(&allSigs);
sigprocmask(SIG_SETMASK, &allSigs, NULL);
Hiç yorum yok:
Yorum Gönder