Killall'e karşı kinder / gentler / subtler eşdeğeri (örn. “Endall”)?


17

Aynı ada sahip tüm işlemleri nasıl yaptığımdan daha yumuşak bir şekilde nasıl sonlandırabilirim killall? İşlemleri kesmek istemiyorum, ancak düzgün bir şekilde bırakmaları için zaman ayırın.


Ayrıca bakınız:

Ubuntu'daki işlemleri nasıl öldürürüm?

Sistem monitöründe, Öldürme Süreci ile Son İşlem arasındaki fark nedir?

Neden killall (bazen?) İki kez uygulanmalıdır?

tl; Dr.


1
Ve sorunuz nedir?
Pilot6

@ Pilot6 yeniden ifade edildi: killall'a "daha yumuşak" bir alternatif nedir?
natty hakkında ceviz

1
"Daha yumuşak" nedir?
Pilot6

Yanıtlar:


43

1. killall zaten güzel (SIGTERM)

killallvarsayılan olarak gönderir SIGTERM. Bu zaten uygulamalara kendileri temizleme şansı veren hoş bir yaklaşım. "Git zaten öl, şimdi!" yaklaşımı, SIGKILLbir seçenek olarak belirtilmesi gereken bir sinyal göndermektir .killall . Gönderen GNU C Kütüphanesi: Sonlandırma Sinyalleri :

Makro: İnt SIGTERM adlı

[...] Kibarca davranmanın normal yolu budur bir programın sonlandırılmasını istemenin .


2. Sistem Monitörünün "İşlemi sonlandır" eşit derecede güzel (SIGTERM)

GNOME Sistem Monitörü ile ilgili bir soruya bağlantı veriyorsunuz. KullanırSIGTERM , "Son süreci" eylemi için de kullanmaktadır (ve bu sorunun cevabıyla çeliştiğimin farkındayım). Kendinizi doğrulamak için kaynak kodunda bulabilirsiniz:

Veri / menus.ui :

<item>
  <attribute name="label" translatable="yes">_End</attribute>
  <attribute name="action">win.send-signal-end</attribute>
  <attribute name="accel">&lt;Primary&gt;e</attribute>
  <attribute name="target" type="i">15</attribute>
</item>

Burada 15, sinyal numarasıdır. Sinyal 15'dir SIGTERM. Ve System Monitor kullandıSIGTERM bu diğer soru sorulmadan ve cevaplanmadan önce çok iyi .


Teknik zeyilname (bir yoruma yanıt olarak)

Github temsiline baktığımızda git blame, GNOME Sistem Monitörü kaynak kodunda sinyallerin nasıl belirtildiği konusunda yapılan değişiklikler şunlardır:

383007f2 24 Tem 2013 GAction parametreleri ile sinyal göndermek için çoğaltılmış kod değiştirildi
0e766b2d 18 Tem 2013 GAction
97674c79'a bağlantı noktası işlemi açılır menüsü 3 Ekim 2012 ProcData yapısından kurtulun
38c5296c 3 Tem 2011 Kaynak dosyalar arasında girinti üniforma yapın.

Bunların hiçbiri 'den' SIGQUITe değişmedi SIGTERMve sonuncusu bağlantılı soru sorulmadan önceydi.


7
Kaynak koduna atıfta bulunmak için +1! (Olduğu gibi "geleneksel bilgelik" ile çelişki için +2;)
natty hakkında ceviz

Cevapla çeliştiğinizi belirtmeden önce: kaynak kodun tüm sürümlerinin kullanıldığını kontrol ettiniz mi 15? Bir noktada değiştirilmiş olabilir, böylece eski cevap eski bir versiyona göre% 100 doğru olabilir .
Bakuriu

1
@Bakuriu Bu cevabı her iki şekilde de çelişiyorum, ama adil bir nokta, bir dahaki sefere bunu kontrol etmeyi hatırlamaya çalışacağım.
hvd

@Bakuriu kaynak git ağacında, git grep 'SIGQUIT'hiçbir şey açığa vurmuyor . Her git grep '>3<'ikisi için de sinyallerle ilgili bir şey bulunamadı . Büyük olasılıkla gnome-system-monitor'un hiç kullanmadığı sonucuna varıyorum SIGQUIT.
Ruslan

@Ruslan git grep, tüm geçmişi değil, sadece geçerli ağacı arar. Kullandığım git blamehala hiçbir biraz daha derine kazmak (aslında Github eşdeğer), ancak.
hvd

5

@Hvd tarafından verilen cevap temel olarak doğrudur. Bunu daha da yedeklemek için, initişlem önce SIGTERMbilgisayarınızı kapattığınızda işlemlere gönderilir , daha sonra SIGKILLhenüz çıkmamışlarsa bir gecikmeden sonra gönderilir. İşlemler işleyemez / yok sayamaz SIGKILL.

Yine de biraz daha ayrıntı vermek gerekirse, asıl cevap, programın onu ele aldığından emin olmanın hiçbir yolu olmadığıdır. SIGTERMkibarca bir programdan çıkmasını istemek için kullanılan en yaygın sinyaldir, ancak tüm sinyal işleme, sinyalle bir şeyler yapan programa bağlıdır.

Diğer cevaplara dayanarak, farklı bir şekilde ifade etmek gerekirse, @Jos veya @AlexGreg tarafından yazılmış bir programınız olsaydı, muhtemelen ele alıyorlardı, SIGQUITama muhtemelen değillerdi SIGTERMve bu nedenleSIGTERM daha az "yumuşak" olurdu SIGQUIT.

Bazı kodlar yazdım, böylece onunla oynayabilirsin. Aşağıdakini farklı kaydedin signal-test.c, ardından derleyin

gcc -o signal-test signal-test.c

Daha sonra onu çalıştırabilir ./signal-testve farklı sinyaller gönderdiğinizde ne olacağını görebilirsiniz killall -s <signal>.

#include <stdio.h>
#include <signal.h>
#include <unistd.h>

int flag = 0;

void handle_signal(int s)
{
    flag = s;
}

int main(int argc, char *argv[])
{
    signal(SIGTERM, handle_signal);
    signal(SIGQUIT, handle_signal);

    while(flag == 0){
        sleep(1);
    }
    printf("flag is %d\n", flag);
    return flag;
}

Durduğu gibi, kod hem SIGTERM hem de SIGQUIT'i zarif bir şekilde işler. Sinyal işleyiciyi kaldırmak için satırları yorumlamayı deneyebilirsiniz signal(SIG...( //satırın başında a kullanarak ), ardından çalıştırıp sinyalleri tekrar gönderin. Bu farklı çıktıları görebilmeniz gerekir:

$ ./signal-test
Terminated

$ ./signal-test
Quit (core dumped)

$ ./signal-test
flag is 15

$ ./signal-test
flag is 3

sinyalleri idare edip etmemenize bağlı olarak.

Sinyalleri görmezden gelmeyi de deneyebilirsiniz:

signal(SIGTERM, SIG_IGN);

Bunu yaparsanız, gönderme SIGTERMhiçbir şey yapmaz, kullanmanız gerekirSIGKILL , işlemi sonlandırmak gerekir.

İçinde daha fazla ayrıntı man 7 signal. Kullanarak unutmayınsignal()Bu şekilde taşınabilir olmayan olarak kabul edildiğini - yine de alternatiften çok daha kolay!

Solaris ile ilgili bir diğer küçük dipnot killalltüm süreçleri öldürmeye çalışıyor. Hepsi. Kök olarak çalıştırırsanız şaşırabilirsiniz :)


1
Tercih ettiğim sebeplerden biri de bu pkill. Diğer neden, pgrepeşleşmesi, hangi işlemlerin öldürüleceğini tam olarak kontrol etmeyi ve hangisinin kendisinden daha iyi eşleşen semantiğe sahip olmasını kontrol etmesidir ps | grep.
Random832

1

"Hepsini bitir" olurdu killall -s SIGQUIT [process name]. Süslü bir çözüm istiyorsanız tanımlayın alias endall='killall -s SIGQUIT'.


13
SIGQUITsüreci yapmak gibidir abort(3): çekirdeği boşaltır ve sonra süreci öldürür. Bu hiçbir şekilde SIGTERMvarsayılan olandan daha hoş / nazik / kinder değildir killall.
Ruslan

3
Sinyalleri işleyen bir işlem için SIGQUIT(veya daha iyisi), SIGINTdaha yumuşak bir şekilde tedavi edilebilir SIGTERM, ancak bu uygulamaya bağlıdır. İşlenmediğinde, bunların herhangi biri derhal feshedilir.
R .. GitHub BUZA YARDIMCI DURDUR

1
Diskinizin her tarafındaki çekirdek dosyaları temizlemeyi seviyorsanız, bu harika bir fikirdir.
Nate Eldredge

2
@Qix: Sinyal başına değişen bir şey, varsayılan eylemde (uygulama tarafından işlenmediğinde) bir çekirdek dosya oluşturup oluşturmadığıdır. Temel dosyalar oluşturmayan sinyalleri kullanmak muhtemelen tercih edilir.
R .. GitHub BUZA YARDIMCI DURDUR

1
Ubuntu'nun çekirdek dosya boyutu sınırını varsayılan olarak 0 olarak ayarladığını belirtmek gerekir, bu nedenle sınırı değiştirmezseniz SIGQUIT aslında bir çekirdek dosya oluşturmaz (işlenmezse).
Roger Light
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.