Çeşitli sinyallerin gönderilmesine neden olan nedir?


28

Bazen bir sürecin alabileceği tüm sinyallerle biraz kafam karışıyor. Anladığım kadarıyla, bir işlem bu sinyallerin her biri için varsayılan bir işleyiciye ( sinyal yerleştirme ) sahiptir, ancak arayarak kendi işleyicisini sağlayabilir sigaction().

İşte benim sorum şu: sinyallerin her birinin gönderilmesine neden olan nedir? -sParametreleri kullanarak çalışan işlemlere manuel olarak sinyal gönderebileceğinizi biliyorum kill, ancak bu sinyallerin gönderildiği doğal koşullar nelerdir? Örneğin, ne zaman SIGINTgönderilir?

Ayrıca, hangi sinyallerin kullanılabileceği konusunda herhangi bir kısıtlama var mı? SIGSEGVSinyaller bile işlenebilir ve kontrol uygulamaya geri döndürülebilir mi?


Bunun doğru bir cevabı epik olacak ve temelde Wikipedia hakkındaki makaledeki bilgiyi kopyalayacak , o yüzden sadece oraya işaret edeceğim.
Shawn J. Goff

@Shawn: Wikipedia makalesinde bir sinyal listesi var, ancak kimin hangi sinyalleri gönderdiğine dair net bir sunum yok.
Gilles 'SO- kötülük'

Yanıtlar:


41

Çağrılan işlemlere ek olarak kill(2), bazı durumlarda çekirdek tarafından (veya bazen işlemin kendisi tarafından) bazı sinyaller gönderilir:

  • Terminal sürücüleri çeşitli olaylara karşılık gelen sinyalleri gönderir:
    • Tuş basma bildirimleri: SIGINT(lütfen ana döngüye geri dönün) Ctrl+ C, + SIGQUIT(lütfen hemen çıkın) Ctrl+ \, SIGTSTP(lütfen askıya alın) Ctrl+ Z. Tuşlar sttykomutla değiştirilebilir .
    • SIGTTINve SIGTTOUbir arka plan işlemi kontrol terminaline okumaya veya yazmaya çalıştığında gönderilir.
    • SIGWINCH terminal penceresinin boyutunun değiştiğini bildirmek için gönderilir.
    • SIGHUPTerminal kaybolduğunu sinyali gönderilir (modeminizin çünkü tarihsel olarak h ung up , günümüzde genellikle terminal emülatörü penceresini kapattıktan çünkü).
  • Bazı işlemci tuzakları bir sinyal üretebilir. Detaylar mimariye ve sisteme bağlıdır; İşte tipik örnekler:
    • SIGBUS Hizalanmamış erişim hafızası için;
    • SIGSEGV eşlenmemiş bir sayfaya erişim için;
    • SIGILL geçersiz bir talimat için (hatalı kod);
    • SIGFPEhatalı argümanlarla kayan nokta talimatı için (örneğin sqrt(-1)).
  • Bazı sinyaller, hedef işlemi bazı sistem olaylarının meydana geldiğini bildirir:
    • SIGALRMİşlem tarafından ayarlanan bir zamanlayıcının süresinin dolduğunu bildirir. Zamanlayıcılar ile set olabilir alarm, setitimerve diğerleri.
    • SIGCHLD Çocuklarından birinin öldüğü bir süreci bildirir.
    • SIGPIPEokuma ucu kapatıldığında bir işlem bir boruya yazmaya çalıştığında üretilir (fikir kaçar foo | barve çıkarsanız a tarafından öldürülür ).barfooSIGPIPE
    • SIGPOLL(ayrıca çağrılır SIGIO), gizlenebilir bir olayın meydana geldiği süreci bildirir. POSIX, üzerinden kaydedilen gizlenebilir olayları belirtir I_SETSIG ioctl. Çoğu sistem, O_ASYNC fcntlbayrakla belirlenen herhangi bir dosya tanıtıcısında gizlenebilir olaylara izin verir . İlgili bir sinyal, SIGURGbir cihazda (yoluyla kaydedilmiş I_SETSIG ioctl) veya soketteki acil verileri bildiren bir sinyaldir .
    • Bazı sistemlerde, UPS güç kesintisinin geldiğini bildirdiğinde SIGPWRtüm işlemlere gönderilir .

Bu listeler ayrıntılı değildir. Standart sinyaller içinde tanımlanmıştır signal.h.

Çoğu sinyal uygulama tarafından yakalanabilir ve kullanılabilir (veya yoksayılabilir). Yakalanamayan sadece iki taşınabilir sinyal SIGKILL(sadece ölür) ve STOP(yürütmeyi durdurur).

SIGSEGV( segmentasyon hatası ) ve kuzeni SIGBUS( otobüs hatası ) yakalanabilir, ancak ne yaptığınızı gerçekten bilmiyorsanız, bu kötü bir fikirdir. Bunları yakalamak için yaygın bir uygulama, bir yığın izleme veya diğer hata ayıklama bilgilerini yazdırmaktır. Daha gelişmiş bir uygulama, bir tür işlem içi bellek yönetimi uygulamak veya sanal makine motorlarında hatalı komutları yakalamaktır.

Sonunda, sinyal olmayan bir şeyden bahsedeyim. Terminalden giriş okuyan bir programdaki bir satırın başında Ctrl+ tuşuna bastığınızda D, programa giriş dosyasının sonuna ulaşıldığını bildirir. Bu bir sinyal değil: giriş / çıkış API'si üzerinden iletilir. Gibi Ctrl+ Cve arkadaşları, anahtar ile yapılandırılabilir stty.


SIGHUP, modeminiz kapatıldı. :-)
Keith

1
Unutulmaması gereken başka bir şey: SIGFPEbiraz garip bir şekilde, tamsayı sıfıra bölme ve bazen de imzalı tamsayı taşması sinyalleridir .
efemient

18

Önce ikinci sorunuzu cevaplamak için: SIGSTOPve SIGKILLuygulama tarafından yakalanamazsınız, ancak diğer tüm sinyaller bile olabilir SIGSEGV. Bu özellik hata ayıklama için kullanışlıdır - örneğin, doğru kütüphane desteğiyle, SIGSEGVyalnızca bu segfault'un nerede olduğunu göstermek için bir yığın geriye izleme dinleyebilir ve oluşturabilirsiniz.

Her man 7 signalkomutun ne yaptığı hakkındaki resmi bir kelime (Linux için zaten) bir Linux komut satırından yazarak kullanılabilir . http://linux.die.net/man/7/signal aynı bilgiler, ancak tablolar okumak zordur.

Ancak, sinyallerle ilgili bir deneyim olmadan, pratikte ne yaptıklarını kısa açıklamalardan bilmek zor, işte benim yorumum:

Klavyeden tetiklendi

  • SIGINTvurduğunda olur CTRL+C.
  • SIGQUITtarafından tetiklenir CTRL+\ve çekirdek dökülür.
  • SIGTSTPvurduğunuzda programınızı askıya alır CTRL+Z. Bunun aksine SIGSTOP, programların, vikendilerini askıya almadan önce terminali güvenli bir duruma getirme şansı gibi programları verir .

Terminal etkileşimleri

  • SIGHUP ("takılma"), programınız çalışırken xterm'inizi kapattığınızda (veya terminalin bağlantısını kesdiğinizde) olan şeydir.
  • SIGTTINve SIGTTOUarka planda çalışırken terminalden okumaya veya terminale yazmaya çalışırsa programınızı duraklatın. Bunun için SIGTTOU, programın /dev/ttysadece standart stdout'a değil, yazması gerektiğini düşünüyorum .

Bir CPU istisnası tarafından tetiklendi

Bunlar, programınızın yanlış bir şey yapmaya çalıştığı anlamına gelir.

  • SIGILLyasadışı veya bilinmeyen bir işlemci talimatı anlamına gelir. Örneğin, işlemci G / Ç bağlantı noktalarına doğrudan erişmeye çalıştıysanız bu olabilir.
  • SIGFPEbir donanım matematik hatası olduğu anlamına gelir; büyük olasılıkla program sıfıra bölmeye çalıştı.
  • SIGSEGV programınızın eşlenmemiş bir hafıza bölgesine erişmeye çalıştığı anlamına gelir.
  • SIGBUSprogramın belleğe başka bir şekilde yanlış girdiği anlamına gelir; Bu özete ilişkin ayrıntılara girmeyeceğim.

Süreç etkileşimi

  • SIGPIPEBorunun okuyucusu uçlarını kapattıktan sonra bir boruya yazmaya çalışırsanız olur. Bakın man 7 pipe.
  • SIGCHLDYarattığınız bir çocuk işlemi ya sona erdiğinde ya da askıya alındığında olur (tarafından SIGSTOPveya benzer şekilde).

Kendi kendine sinyal verme için kullanışlıdır

  • SIGABRTgenellikle abort()işlevi çağıran programdan kaynaklanır ve varsayılan olarak bir çekirdek dökümüne neden olur. Bir "panik butonunun" sıralaması.
  • SIGALRMkaynaklanır alarm()çekirdek bir teslim neden olacak sistem çağrısı, SIGALRMsaniye belirli bir sayıda sonra programa. Bkz man 2 alarmve man 2 sleep.
  • SIGUSR1ve SIGUSR2programın sevdiği ancak kullanılır. İşlemler arasında sinyal göndermede faydalı olabilirler.

Yönetici tarafından gönderildi

Bu sinyaller genellikle komut isteminden, killkomut aracılığıyla veya fgveya bgdurumunda gönderilir SIGCONT.

  • SIGKILLve SIGSTOPengellenemez sinyaller. İlki her zaman süreci derhal sonlandırır; ikincisi süreci askıya alır.
  • SIGCONT askıya alınmış bir işlemi sürdürür.
  • SIGTERMbir yakalanabilir sürümüdür SIGKILL.

shutdownKomut kullanıldığında hangi sinyal gönderilir ?
Nathan Osman

Bu kapatma komut dosyalarına bağlıdır. Genellikle, SIGTERMönce gönderilir, ardından bir gecikme, ardından gelir SIGKILL. Prensip olarak, sert ve acil bir kapanış için çekirdeğin bir sinyal göndermesi gerekmez; süreci sürdürmeyi bırakabilirdi.
Jander
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.