คุณ / kentler / subtler เทียบเท่ากับ killall (เช่น“ endall”)?


17

ฉันจะจบกระบวนการทั้งหมดด้วยชื่อเดียวกันด้วยวิธีที่อ่อนโยนกว่าได้killallอย่างไร? ฉันไม่ต้องการที่จะขัดจังหวะกระบวนการ แต่ปล่อยให้พวกเขามีเวลาที่จะออกจากอย่างถูกต้อง


ดูสิ่งนี้ด้วย:

ฉันจะฆ่ากระบวนการใน Ubuntu ได้อย่างไร

ในการตรวจสอบระบบอะไรคือความแตกต่างระหว่าง Kill Process และ End Process?

เหตุใด killall (บางครั้ง) จึงจำเป็นต้องใช้สองครั้ง

TL; DR


1
และคำถามของคุณคือ?
Pilot6

@ Pilot6 re-phrased:อะไรคือ "ทางเลือก" ที่นุ่มนวลกว่าในการ Killall?
บ๊องเกี่ยวกับ natty

1
"นุ่มนวล" คืออะไร?
Pilot6

คำตอบ:


43

1. `killall` ดีอยู่แล้ว (SIGTERM)

killallSIGTERMโดยค่าเริ่มต้นส่ง นี่คือแล้ววิธีการที่ดีที่การใช้งานใบโอกาสที่จะทำความสะอาดหลังจากที่ตัวเอง "ไปตายแล้วตอนนี้!" วิธีการคือการส่งสัญญาณซึ่งจะต้องมีการระบุว่าเป็นตัวเลือกให้กับSIGKILL killallจากห้องสมุด GNU C: สัญญาณการสิ้นสุด :

มาโคร: int SIGTERM

[... ] เป็นวิธีปกติในการขอให้โปรแกรมยุติอย่างสุภาพ


2. "กระบวนการสิ้นสุด" ของ System Monitor ที่ดีไม่แพ้กัน (SIGTERM เช่นกัน)

คุณเชื่อมโยงกับคำถามเกี่ยวกับการตรวจสอบระบบของ GNOME นั่นใช้SIGTERMสำหรับการกระทำ "End process" ด้วย (และฉันรู้ว่าฉันขัดแย้งกับคำตอบของคำถามนั้น) คุณสามารถค้นหาได้ในซอร์สโค้ดเพื่อยืนยันตัวเอง:

data / menu.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>

15 นี่คือหมายเลขสัญญาณ สัญญาณ SIGTERM15 และการตรวจสอบระบบใช้งานได้SIGTERMดีก่อนที่คำถามอื่นจะถูกถามและตอบ


ภาคผนวกทางเทคนิค (เพื่อตอบสนองต่อความคิดเห็น)

เมื่อมองผ่านการเป็นตัวแทน Github git blameนี่คือการเปลี่ยนแปลงที่เกิดขึ้นกับวิธีการสะกดสัญญาณในซอร์สโค้ดของ GNOME System Monitor:

383007f2 24 ก.ค. 2556 แทนที่รหัสซ้ำสำหรับการส่งสัญญาณด้วยพารามิเตอร์
GAction 0e766b2d 18 ก.ค. 2556 เมนูป๊อปอัปกระบวนการพอร์ตไปยัง GAction
97674c79 3 ต.ค. 2555 กำจัดโครงสร้าง
ProcData 38c5296c 3 กรกฎาคม 2554

สิ่งเหล่านี้ไม่เปลี่ยนจากSIGQUITเป็นSIGTERMและสุดท้ายเป็นคำถามก่อนถามคำถามที่เชื่อมโยง


7
+1 สำหรับการอ้างอิงถึงซอร์สโค้ด! (+2 สำหรับการโต้แย้ง "ภูมิปัญญาดั้งเดิม" ตามที่เคยเป็น;)
nutty about natty

ก่อนที่จะระบุว่าคุณขัดแย้งกับคำตอบ: คุณตรวจสอบว่าซอร์สโค้ดทุกเวอร์ชันใช้15หรือไม่? อาจมีการเปลี่ยนแปลงในบางจุดเพื่อให้คำตอบเก่าอาจถูก 100% เทียบกับเวอร์ชั่นเก่า
Bakuriu

1
@Bakuriu ฉันขัดแย้งกับคำตอบอย่างใดอย่างหนึ่ง แต่จุดที่เป็นธรรมฉันจะพยายามอย่าลืมตรวจสอบในครั้งต่อไปที่ฉันสามารถ
hvd

@Bakuriu ในซอร์ส git tree git grep 'SIGQUIT'ไม่เปิดเผยอะไรเลย ไม่มีอะไรที่เกี่ยวข้องกับการส่งสัญญาณจะพบgit grep '>3<'อย่างใดอย่างหนึ่ง ผมสรุปได้ว่าส่วนใหญ่มีแนวโน้ม SIGQUITgnome-ระบบจอภาพยังไม่เคยใช้
Ruslan

@Ruslan git grepค้นหาเฉพาะต้นไม้ปัจจุบันไม่ใช่ประวัติทั้งหมด ฉันใช้git blame(จริง ๆ แล้วเทียบเท่ากับ Github) เพื่อขุดลึกลงไปอีกเล็กน้อย แต่ก็ยังไม่มีอะไร
hvd

5

คำตอบโดย @hvd นั้นถูกต้องแล้ว ในการสำรองข้อมูลให้มากขึ้นinitขั้นตอนแรกจะส่งSIGTERMไปยังกระบวนการต่างๆเมื่อคุณปิดระบบคอมพิวเตอร์ของคุณจากนั้นหลังจากการหน่วงเวลาจะส่งSIGKILLหากพวกเขายังไม่ออก กระบวนการไม่สามารถจัดการ / เพิกเฉยSIGKILLได้

เพื่อให้รายละเอียดเพิ่มเติมเล็กน้อยคำตอบที่แท้จริงคือคุณไม่มีทางรู้แน่ชัดว่าโปรแกรมนั้นจัดการกับมัน SIGTERMเป็นสัญญาณปกติที่สุดที่ใช้สำหรับขอให้โปรแกรมออกอย่างสุภาพ แต่การจัดการสัญญาณทั้งหมดขึ้นอยู่กับโปรแกรมที่ทำบางอย่างกับสัญญาณ

ที่จะนำมันเป็นวิธีที่แตกต่างกันขึ้นอยู่กับคำตอบอื่น ๆ ถ้าคุณมีโปรแกรมที่เขียนโดย @Jos หรือ @AlexGreg แล้วพวกเขาก็คงจะต้องจัดการSIGQUITแต่อาจจะไม่ได้SIGTERMและด้วยเหตุนี้การส่งSIGTERMจะน้อย "อ่อน" SIGQUITกว่า

ฉันเขียนโค้ดบางส่วนเพื่อให้คุณสามารถเล่นกับมันด้วยตัวเอง บันทึกด้านล่างเป็นsignal-test.cแล้วรวบรวมด้วย

gcc -o signal-test signal-test.c

จากนั้นคุณสามารถเรียกใช้มันและดูสิ่งที่เกิดขึ้นเมื่อคุณส่งสัญญาณที่แตกต่างกันด้วย./signal-testkillall -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;
}

ตามที่เป็นอยู่รหัสจะจัดการทั้ง SIGTERM และ SIGQUIT อย่างงดงาม คุณสามารถลองแสดงความคิดเห็นในบรรทัดsignal(SIG...(โดยใช้//ที่จุดเริ่มต้นของบรรทัด) เพื่อลบตัวจัดการสัญญาณจากนั้นเรียกใช้และส่งสัญญาณอีกครั้ง คุณควรจะเห็นผลลัพธ์ต่าง ๆ เหล่านี้:

$ ./signal-test
Terminated

$ ./signal-test
Quit (core dumped)

$ ./signal-test
flag is 15

$ ./signal-test
flag is 3

ขึ้นอยู่กับว่าคุณจัดการสัญญาณหรือไม่

คุณสามารถลองละเว้นสัญญาณ:

signal(SIGTERM, SIG_IGN);

หากคุณทำเช่นนั้นการส่งSIGTERMจะไม่ทำอะไรเลยคุณจะต้องใช้SIGKILLเพื่อสิ้นสุดกระบวนการ

man 7 signalรายละเอียดเพิ่มเติมใน โปรดทราบว่าการใช้signal()วิธีนี้ถือว่าไม่ใช่แบบพกพา - มันง่ายกว่าตัวเลือกอื่น ๆ !

เชิงอรรถย่อยอีกหนึ่งเรื่อง - บน Solaris killallพยายามฆ่ากระบวนการทั้งหมด ทั้งหมด. หากคุณเรียกใช้มันในฐานะ root คุณอาจประหลาดใจ :)


1
pkillนี้เป็นหนึ่งในเหตุผลที่ผมต้องการ เหตุผลอื่น ๆ ก็คือว่ามันคู่ซึ่งทำให้ง่ายต่อการตรวจสอบว่าสิ่งที่กระบวนการจะถูกฆ่าและที่ตัวเองมีความหมายตรงกับที่ดีกว่าpgrep ps | grep
Random832

1

"End ทั้งหมด" killall -s SIGQUIT [process name]จะเป็น alias endall='killall -s SIGQUIT'หากคุณต้องการแก้ปัญหาแฟนซีกำหนด


13
SIGQUITมันก็เหมือนกับการทำให้กระบวนการabort(3): มันทิ้งแกนแล้วฆ่ากระบวนการ นี้เป็นในทางที่ดีกว่า / นุ่มนวล / เมตตากว่าซึ่งเป็นค่าเริ่มต้นSIGTERM killall
Ruslan

3
สำหรับกระบวนการที่จัดการสัญญาณSIGQUIT(หรือดีกว่าSIGINT) อาจได้รับการปฏิบัติที่ 'เบากว่า' มากกว่าSIGTERMแต่นี่ขึ้นอยู่กับแอปพลิเคชัน ไม่จัดการใด ๆ ของพวกเขาทำให้เกิดการยกเลิกทันที
. GitHub หยุดช่วยน้ำแข็ง

1
นี่เป็นความคิดที่ดีหากคุณต้องการล้างไฟล์คอร์ทั่วดิสก์ของคุณ
Nate Eldredge

2
@Qix: สิ่งหนึ่งที่แตกต่างกันต่อสัญญาณคือมันสร้างไฟล์หลักหรือไม่ในการดำเนินการเริ่มต้น (เมื่อไม่ได้รับการจัดการโดยแอปพลิเคชัน) มันอาจจะดีกว่าถ้าใช้สัญญาณที่ไม่ได้สร้างไฟล์คอร์
. GitHub หยุดช่วยเหลือน้ำแข็ง

1
เป็นที่น่าสังเกตว่าอูบุนตูตั้งค่าขนาดไฟล์หลักไว้ที่ 0 โดยค่าเริ่มต้นดังนั้น SIGQUIT จะไม่สร้างไฟล์หลัก (ถ้าไม่จัดการ) เว้นแต่ว่าคุณจะแก้ไขข้อ จำกัด
Roger Light
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.