ลินุกซ์“ ฆ่า” กระบวนการอย่างไร?


91

บ่อยครั้งที่ทำให้ฉันงงงันแม้ว่าฉันจะทำงานกับคอมพิวเตอร์เป็นเวลาหลายสิบปีและลีนุกซ์เป็นเวลาสิบปี แต่ฉันก็ยังใช้งานฟังก์ชั่นส่วนใหญ่ของระบบปฏิบัติการได้เหมือนกล่องดำ

วันนี้ฉันคิดเกี่ยวกับkillคำสั่งและในขณะที่ฉันใช้มันหลายครั้งต่อวัน (ทั้งใน "ปกติ" และ-9รสชาติ) ฉันต้องยอมรับว่าฉันไม่รู้ว่ามันใช้งานได้อย่างไรอยู่เบื้องหลัง

จากมุมมองของฉันหากกระบวนการทำงานเป็น "หยุด" ฉันเรียกkillใช้ PID ของมันและจากนั้นจะไม่ทำงานอีกต่อไป มายากล!

เกิดอะไรขึ้นจริง ๆ หน้าพูดคุยเกี่ยวกับ "สัญญาณ" แต่แน่นอนว่าเป็นเพียงนามธรรม การส่งkill -9ไปยังกระบวนการไม่ต้องการความร่วมมือของกระบวนการ (เช่นการจัดการสัญญาณ) มันแค่ฆ่ามันออกไป

  • Linux หยุดกระบวนการไม่ให้ใช้เวลา CPU ต่อไปอย่างไร
  • มันถูกลบออกจากการตั้งเวลา?
  • มันยกเลิกการเชื่อมต่อกระบวนการจากตัวจัดการไฟล์ที่เปิดอยู่หรือไม่?
  • หน่วยความจำเสมือนของกระบวนการเปิดตัวอย่างไร
  • มีบางสิ่งที่เหมือนตารางทั่วโลกในหน่วยความจำที่ลีนุกซ์อ้างอิงทรัพยากรทั้งหมดที่เกิดขึ้นจากกระบวนการและเมื่อฉัน "ฆ่า" กระบวนการลีนุกซ์จะผ่านตารางนั้นและปลดปล่อยทรัพยากรทีละตัว?

ฉันอยากรู้ทุกอย่างจริงๆ!


7
บังคับkill -9อ้างอิง
Jon

คำตอบของฉันสำหรับคำถามเกี่ยวกับ SIGKILLนั้นอาจเกี่ยวข้องกับที่นี่
telcoM

คำตอบ:


72

การส่ง kill -9 ไปยังกระบวนการไม่ต้องการความร่วมมือของกระบวนการ (เช่นการจัดการสัญญาณ) มันแค่ฆ่ามันออกไป

คุณกำลังสันนิษฐานว่าเพราะสัญญาณบางอย่างสามารถถูกจับได้และไม่สนใจพวกมันล้วนเกี่ยวข้องกับความร่วมมือ แต่ตามman 2 signal" สัญญาณ SIGKILL และ SIGSTOP ไม่สามารถจับหรือเพิกเฉยได้" SIGTERM สามารถถูกจับได้ซึ่งเป็นสาเหตุว่าทำไมที่ราบkillไม่ได้มีประสิทธิภาพเสมอไป - โดยทั่วไปนี่หมายถึงบางสิ่งในตัวจัดการของกระบวนการผิดพลาด 1

หากกระบวนการไม่ได้ (หรือไม่สามารถกำหนดตัวจัดการสำหรับสัญญาณที่กำหนดได้เคอร์เนลจะทำการกระทำเริ่มต้น ในกรณีของ SIGTERM และ SIGKILL นี่คือการยกเลิกกระบวนการ (เว้นแต่ว่า PID ของมันคือ 1; เคอร์เนลจะไม่ยุติinit) 2 หมายถึงการจัดการไฟล์ถูกปิดหน่วยความจำของมันจะถูกปิดหน่วยความจำของมันกลับไปยังกลุ่มระบบ เด็ก ๆ ได้รับการสืบทอดโดย init เป็นต้นเช่นเดียวกับที่เรียกexit(ดูman 2 exit) กระบวนการไม่มีอยู่อีกต่อไป - เว้นแต่ว่ามันจะกลายเป็นซอมบี้ซึ่งในกรณีนี้มันยังคงอยู่ในตารางกระบวนการของเคอร์เนลที่มีข้อมูลบางอย่าง ที่เกิดขึ้นเมื่อผู้ปกครองไม่ได้waitและจัดการกับข้อมูลนี้อย่างถูกต้อง อย่างไรก็ตามกระบวนการซอมบี้จะไม่มีการจัดสรรหน่วยความจำใด ๆ อีกต่อไปดังนั้นจึงไม่สามารถดำเนินการต่อได้

มีบางสิ่งที่เหมือนตารางทั่วโลกในหน่วยความจำที่ลีนุกซ์อ้างอิงทรัพยากรทั้งหมดที่เกิดขึ้นจากกระบวนการและเมื่อฉัน "ฆ่า" กระบวนการลีนุกซ์จะผ่านตารางนั้นและปลดปล่อยทรัพยากรทีละตัว?

ฉันคิดว่ามันแม่นยำพอ หน่วยความจำกายภาพถูกติดตามโดยหน้า (หนึ่งหน้ามักจะมีขนาดเท่ากับ 4 KB) และหน้าเหล่านั้นจะถูกนำมาจากและกลับสู่กลุ่มรวม มันซับซ้อนกว่าเล็กน้อยในการที่เพจที่ถูกปล่อยบางหน้าจะถูกแคชในกรณีที่จำเป็นต้องใช้ข้อมูลอีกครั้ง (นั่นคือข้อมูลที่อ่านจากไฟล์ที่มีอยู่แล้ว)

หน้าพูดคุยเกี่ยวกับ "สัญญาณ" แต่แน่นอนว่ามันเป็นเพียงนามธรรม

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

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

void sighandler (int signum, siginfo_t *info, void *context) {
    fprintf (
        stderr,
        "Received %d from pid %u, uid %u.\n",
        info->si_signo,
        info->si_pid,
        info->si_uid
    );
}

int main (void) {
    struct sigaction sa;
    memset(&sa, 0, sizeof(sa));
    sa.sa_sigaction = sighandler;
    sa.sa_flags = SA_SIGINFO;
    sigaction(SIGTERM, &sa, NULL);
    while (1) sleep(10);
    return 0;
}

กระบวนการนี้จะนอนหลับตลอดไป คุณสามารถเรียกใช้มันใน terminal และส่ง SIGTERM killกับ มันคายสิ่งต่าง ๆ เช่น:

Received 15 from pid 25331, uid 1066.

1,066 เป็น UID ของฉัน PID จะเป็นของเชลล์ที่killถูกเรียกใช้งานหรือ PID ของการฆ่าถ้าคุณแยกมัน ( kill 25309 & echo $?)

อีกครั้งไม่มีจุดในการตั้งค่าตัวจัดการสำหรับ SIGKILL เพราะจะไม่ทำงาน 3ถ้าฉันkill -9 25309กระบวนการจะยุติ แต่นั่นยังคงเป็นสัญญาณ เมล็ดมีข้อมูลเกี่ยวกับที่ส่งสัญญาณสิ่งที่ชนิดของสัญญาณมันเป็น ฯลฯ


1. ถ้าคุณไม่ได้มองไปที่รายการที่เป็นไปได้สัญญาณkill -lให้ดู

2. ข้อยกเว้นอื่น ๆ ตามที่ Tim Post กล่าวถึงด้านล่างนี้ใช้กับกระบวนการในโหมดสลีปที่ไม่สามารถขัดจังหวะได้ สิ่งเหล่านี้ไม่สามารถถูกปลุกให้ตื่นขึ้นได้จนกว่าปัญหาพื้นฐานจะได้รับการแก้ไขและมีสัญญาณทั้งหมด (รวมถึง SIGKILL) รอการตัดบัญชีในช่วงเวลานั้น กระบวนการไม่สามารถสร้างสถานการณ์นั้นได้ตามวัตถุประสงค์

3. สิ่งนี้ไม่ได้หมายความว่าการใช้kill -9เป็นสิ่งที่ควรทำในทางปฏิบัติ exit()จัดการตัวอย่างของฉันเป็นคนหนึ่งที่ไม่ดีในแง่ที่ว่ามันไม่ได้นำไปสู่การ วัตถุประสงค์ที่แท้จริงของตัวจัดการ SIGTERM คือการให้โอกาสในการทำสิ่งต่าง ๆ เช่นล้างไฟล์ชั่วคราวจากนั้นออกโดยสมัครใจ หากคุณใช้kill -9มันจะไม่ได้รับโอกาสนี้ดังนั้นให้ทำเช่นนั้นหากส่วน "ออกโดยสมัครใจ" ดูเหมือนจะล้มเหลว


โอเค แต่สิ่งที่ฆ่ากระบวนการด้วย-9เพราะนั่นเป็นปัญหาที่แท้จริงว่าใครที่ปรารถนาว่าสิ่งนี้จะต้องตาย! ;)
กีวี

@Kiwy: เคอร์เนล IPC รวมถึงสัญญาณที่ส่งผ่าน เคอร์เนลใช้การกระทำเริ่มต้น
goldilocks

12
อาจคุ้มค่าที่จะกล่าวถึงว่า disk sleep (D) ครอบครองสัญญาณทั้งหมดในขณะที่กระบวนการอยู่ในสถานะนั้น ดังนั้นการพยายามทำให้kill -9กระบวนการที่ถูกผูกไว้ I / O บางอย่างไม่ทำงานอย่างน้อยก็ในทันที
Tim Post

7
ฉันจะเพิ่มว่าเนื่องจากkill -9ไม่สามารถจับได้กระบวนการที่ได้รับจะไม่สามารถทำการล้างข้อมูลใด ๆ (เช่นการลบไฟล์ชั่วคราวการเพิ่มหน่วยความจำที่แชร์ ฯลฯ ) ก่อนที่จะออก ดังนั้นให้ใช้kill -9(aka kill -kill) เป็นทางเลือกสุดท้ายเท่านั้น เริ่มต้นด้วยkill -hupและ / หรือkill -termก่อนแล้วจึงใช้kill -killเป็นระเบิดครั้งสุดท้าย
JRFerguson

"กระบวนการไม่มีอยู่อีกต่อไป - เว้นแต่ว่ามันจะกลายเป็นผีดิบในกรณีที่มันยังคงอยู่ในตารางกระบวนการของเคอร์เนลที่มีข้อมูลบางอย่าง" จริง ๆ แล้วกระบวนการทั้งหมดจะเข้าสู่สถานะผีดิบเมื่อพวกเขาตายและซอมบี้จะหายไปเมื่อ ผู้ปกครองไม่ waitpid ในเด็กปกติที่เกิดขึ้นเร็วเกินไปสำหรับคุณที่จะเห็นมันเกิดขึ้น
ฉลาด

3

แต่ละกระบวนการทำงานตามเวลาที่กำหนดและถูกขัดจังหวะโดยตัวจับเวลาฮาร์ดแวร์เพื่อมอบซีพียูหลักสำหรับงานอื่น ๆ นี่คือสาเหตุที่เป็นไปได้ที่จะมีกระบวนการมากกว่า CPU แกนหลักหรือแม้กระทั่งเรียกใช้ระบบปฏิบัติการทั้งหมดที่มีกระบวนการจำนวนมากบน CPU แกนเดียว

หลังจากกระบวนการถูกขัดจังหวะการควบคุมจะกลับไปที่รหัสเคอร์เนล รหัสนั้นสามารถตัดสินใจได้ว่าจะไม่ดำเนินการตามกระบวนการที่ถูกขัดจังหวะโดยไม่ได้รับความร่วมมือจากฝ่ายกระบวนการ kill -9 อาจสิ้นสุดการทำงานในบรรทัดใด ๆ ของโปรแกรมของคุณ


0

นี่คือคำอธิบายในอุดมคติของการฆ่ากระบวนการทำงาน ในทางปฏิบัติตัวแปร Unix ใด ๆ จะมีภาวะแทรกซ้อนและการเพิ่มประสิทธิภาพมากมาย

เคอร์เนลมีโครงสร้างข้อมูลสำหรับแต่ละกระบวนการที่เก็บข้อมูลเกี่ยวกับการแมปหน่วยความจำว่ามีเธรดใดและเมื่อใดที่มีการกำหนดเวลาไฟล์ที่เปิดอยู่เป็นต้นหากเคอร์เนลตัดสินใจที่จะฆ่ากระบวนการ โครงสร้างข้อมูลของกระบวนการ (และอาจอยู่ในโครงสร้างข้อมูลของแต่ละเธรด) ที่กระบวนการนั้นจะถูกฆ่า

หากหนึ่งในเธรดของกระบวนการถูกกำหนดเวลาไว้ใน CPU อื่นเคอร์เนลอาจทริกเกอร์การขัดจังหวะบน CPU อื่นนั้นเพื่อให้เธรดนั้นหยุดดำเนินการได้เร็วขึ้น

เมื่อตัวกำหนดตารางเวลาสังเกตว่าเธรดอยู่ในกระบวนการที่ต้องถูกฆ่าเธรดจะไม่กำหนดเวลาอีกต่อไป

เมื่อไม่มีเธรดของกระบวนการถูกกำหนดเวลาไว้เคอร์เนลจะเริ่มการปลดปล่อยทรัพยากรของกระบวนการ (หน่วยความจำตัวอธิบายไฟล์ ... ) ทุกครั้งที่เคอร์เนลปลดปล่อยทรัพยากรมันจะตรวจสอบว่าเจ้าของยังคงมีทรัพยากรอยู่ เมื่อกระบวนการไม่มีทรัพยากรที่ใช้งานได้อีกต่อไป (การแมปหน่วยความจำ, ตัวอธิบายไฟล์ที่เปิด, ... ) โครงสร้างข้อมูลสำหรับกระบวนการสามารถปล่อยให้เป็นอิสระและรายการที่เกี่ยวข้องสามารถลบออกจากตารางกระบวนการได้

ทรัพยากรบางอย่างสามารถทำให้เป็นอิสระได้ทันที (เช่นการจัดสรรคืนหน่วยความจำที่ไม่ได้ใช้งานโดยการดำเนินการ I / O) แหล่งข้อมูลอื่น ๆ ต้องรอตัวอย่างเช่นข้อมูลที่อธิบายการดำเนินการ I / O ไม่สามารถทำให้เป็นอิสระในขณะที่การดำเนินการ I / O กำลังดำเนินการอยู่ (ในขณะที่DMAอยู่ระหว่างดำเนินการหน่วยความจำที่ใช้งานอยู่ การติดต่ออุปกรณ์ต่อพ่วง) ไดรเวอร์สำหรับทรัพยากรดังกล่าวได้รับแจ้งและอาจพยายามเร่งการยกเลิก เมื่อการดำเนินการไม่ได้อยู่ในระหว่างดำเนินการอีกต่อไปคนขับรถจะปล่อยทรัพยากรนั้นให้เสร็จสิ้น

(รายการในตารางกระบวนการจริง ๆ แล้วเป็นทรัพยากรที่เป็นของกระบวนการหลักซึ่งได้รับการปลดปล่อยเมื่อกระบวนการตายและผู้ปกครองรับทราบเหตุการณ์ )

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