Những gì bạn đang quan sát là một lỗi trong phiên bản bash này.
kill -9 %1
không giết công việc ngay lập tức Bạn có thể quan sát điều đó với ps
. Bạn có thể theo dõi quá trình bash để xem khi nào kill
cuộc gọi hệ thống được gọi và theo dõi tiến trình con để xem khi nào nó nhận và xử lý tín hiệu. Xen kẽ hơn, bạn có thể đi và xem những gì đang xảy ra với quá trình.
bash-4.3$ sleep 9999
^Z
[1]+ Stopped sleep 9999
bash-4.3$ kill -9 %1
[1]+ Stopped sleep 9999
bash-4.3$ jobs
[1]+ Stopped sleep 9999
bash-4.3$ jobs -l
[1]+ 3083 Stopped sleep 9999
bash-4.3$
Trong một thiết bị đầu cuối khác:
% ps 3083
PID TTY STAT TIME COMMAND
3083 pts/4 Z 0:00 [sleep] <defunct>
Quá trình con là một zombie . Nó đã chết: tất cả những gì còn lại của nó là một mục trong bảng quy trình (nhưng không có bộ nhớ, mã, tệp đang mở, v.v.). Mục nhập được để lại xung quanh cho đến khi cha mẹ của nó chú ý và lấy trạng thái thoát của nó bằng cách gọi cuộc gọi wait
hệ thống hoặc một trong những anh chị em của nó .
Một vỏ tương tác có nhiệm vụ kiểm tra những đứa trẻ đã chết và gặt chúng trước khi in một dấu nhắc (trừ khi được cấu hình khác). Phiên bản bash này không thực hiện được trong một số trường hợp:
bash-4.3$ jobs -l
[1]+ 3083 Stopped sleep 9999
bash-4.3$ true
bash-4.3$ /bin/true
[1]+ Killed sleep 9999
Bạn có thể mong đợi bash báo cáo về Kiết chết ngay khi nó in lời nhắc sau kill
lệnh, nhưng điều đó không được đảm bảo, vì có một điều kiện cuộc đua. Tín hiệu được phân phối không đồng bộ: kill
cuộc gọi hệ thống trả về ngay khi hạt nhân đã tìm ra (các) quá trình nào để truyền tín hiệu đến mà không cần chờ nó thực sự được gửi. Điều đó là có thể, và nó đã xảy ra trong thực tế, bash có thời gian để kiểm tra trạng thái của quy trình con của nó, thấy rằng nó vẫn chưa chết ( wait4
không báo cáo bất kỳ cái chết nào của trẻ em) và in rằng quá trình vẫn đang dừng lại. Điều sai là trước lời nhắc tiếp theo, tín hiệu đã được gửi ( ps
báo cáo rằng quá trình đã chết), nhưng bash vẫn chưa được gọiwait4
(chúng ta có thể thấy rằng không chỉ bởi vì nó vẫn báo cáo công việc với tên là Stop Stopped, mà bởi vì zombie vẫn còn hiện diện trong bảng quy trình). Trên thực tế, bash chỉ gặt hái zombie vào lần tiếp theo mà nó cần gọi wait4
, khi nó chạy một số lệnh bên ngoài khác.
Lỗi không liên tục và tôi không thể tái tạo nó trong khi bash được truy tìm (có lẽ vì đó là điều kiện cuộc đua mà bash cần phải phản ứng nhanh). Nếu tín hiệu được phát trước khi kiểm tra bash, mọi thứ sẽ diễn ra như mong đợi.