Để trả lời câu hỏi đó, bạn phải hiểu cách các tín hiệu được gửi đến một quy trình và làm thế nào một quy trình tồn tại trong kernel.
Mỗi quá trình được biểu diễn dưới dạng task_struct
bên trong kernel (định nghĩa nằm trong sched.h
tệp tiêu đề và bắt đầu ở đây ). Cấu trúc đó chứa thông tin về quy trình; ví dụ như pid. Thông tin quan trọng nằm ở dòng 1566 nơi tín hiệu liên quan được lưu trữ. Điều này chỉ được đặt nếu tín hiệu được gửi đến quá trình.
Một quá trình chết hoặc một quá trình zombie vẫn có một task_struct
. Cấu trúc vẫn còn, cho đến khi quá trình cha mẹ (tự nhiên hoặc bằng cách thông qua) đã được gọi wait()
sau khi nhận được SIGCHLD
để gặt hái quá trình con của nó. Khi một tín hiệu được gửi, signal_struct
được đặt. Nó không thành vấn đề nếu tín hiệu có thể bắt được hay không, trong trường hợp này.
Tín hiệu được đánh giá mỗi khi quá trình chạy. Hoặc chính xác, trước khi quá trình sẽ chạy. Quá trình sau đó là trong TASK_RUNNING
nhà nước. Hạt nhân chạy schedule()
thường trình xác định quá trình chạy tiếp theo theo thuật toán lập lịch của nó. Giả sử quá trình này là quá trình chạy tiếp theo, giá trị của signal_struct
được đánh giá, cho dù có tín hiệu chờ xử lý hay không. Nếu một trình xử lý tín hiệu được xác định thủ công (thông qua signal()
hoặc sigaction()
), chức năng đã đăng ký sẽ được thực thi, nếu không thì hành động mặc định của tín hiệu được thực thi. Hành động mặc định phụ thuộc vào tín hiệu được gửi.
Chẳng hạn, SIGSTOP
trình xử lý mặc định của tín hiệu sẽ thay đổi trạng thái của quy trình hiện tại thành TASK_STOPPED
rồi chạy schedule()
để chọn một quy trình mới để chạy. Lưu ý, SIGSTOP
là không thể bắt được (như SIGKILL
), do đó không có khả năng đăng ký một trình xử lý tín hiệu thủ công. Trong trường hợp tín hiệu không thể so sánh được, hành động mặc định sẽ luôn được thực thi.
Cho câu hỏi của bạn:
Một quy trình không còn tồn tại hoặc không còn tồn tại sẽ không bao giờ được xác định bởi người lập lịch để ở trong TASK_RUNNING
trạng thái một lần nữa. Do đó, hạt nhân sẽ không bao giờ chạy trình xử lý tín hiệu (mặc định hoặc được xác định) cho tín hiệu tương ứng, bất kỳ tín hiệu nào là. Do đó, exit_signal
sẽ không bao giờ được thiết lập lại. Tín hiệu được "gửi" đến quy trình bằng cách đặt vào signal_struct
trong task_struct
quy trình, nhưng sẽ không có gì khác xảy ra, vì quy trình sẽ không bao giờ chạy lại. Không có mã để chạy, tất cả những gì còn lại của quá trình là quy trình đó.
Tuy nhiên, nếu tiến trình cha mẹ gặt hái con cái của nó wait()
, mã thoát mà nó nhận được là mã khi quá trình "ban đầu" bị chết. Sẽ không có vấn đề gì nếu có tín hiệu chờ xử lý.
kill
tự trả về 0 hay 1?