Nếu bạn là người dùng Linux, có thể bạn đã từng nhìn thấy những
tiến trình (process) với cái tên khá lạ “Zombie”. Vâng, zombie nghĩa là
thây ma tức là tiến trình đó đã chết và bạn không thể “kill” nó thêm 1
lần nữa. Thú vị đúng không nào.
Zombie thực chất là một phần còn sót lại của một tiến trình đã
ngừng hoạt động nhưng chưa được xử lý sạch. Những chương trình sau khi
thoát để lại tiến trình Zombie thì điều đó đồng nghĩa với việc chương
trình đó được lập trình không tốt.
Vậy chính xác “tiến trình thây ma” được tạo ra như thế nào?
Muốn hiểu chính xác quá trình này, bạn cần có một chút hiểu biết về
cách hoạt động của các tiến trình trong HĐH Linux. Một khái niệm bạn
gần biết nữa là tiến trình cha mẹ (parent process) là tiến trình khi
thực thi tạo ra các tiến trình khác.
Trong Linux, khi một tiến trình kết thúc, HĐH sẽ không xóa nó khỏi
bộ nhớ ngay lập tức. Thay vào đó, Linux vẫn giữ lại mô tả tiến trình
(process discriptor) trong bộ nhớ (Mô tả tiến trình chỉ chiếm một lượng
nhỏ bộ nhớ). Lúc này, trạng thái của tiến trình sẽ là EXIT_ZOMBIE và
“cha mẹ” của tiến trình đó được thông báo rằng tiến trình con đã “chết”
với tín hiệu tên là SIGCHLD. Tiến trình cha mẹ sau đó có nghĩa vụ thực
thi chức năng wait() với nhiệm vụ đọc trạng thái và thông tin của tiến
trình đã chết đó. Sau khi chức năng wait() được gọi, tiến trình Zombie
lúc này sẽ được xóa hoàn toàn khỏi bộ nhớ.
Quá trình này thường diễn ra khá nhanh, vì thế bạn sẽ không thể
nhìn thấy những tiến trình thây ma. Tuy nhiên nếu tiến trình cha mẹ được
lập trình cẩu thả và không bao giờ thực hiện chức năng wait(), tiến
trình thây mà sẽ nằm lại trong bộ nhớ đến khi hệ thống được khởi động
lại.
Để nhìn thấy những tiến trình thây ma, bạn cần cài đặt Top command
hoặc PS command. (GNOME System Monitor không hiển thị tiến trình thây
ma).
Nguy hiểm từ “tiến trình thây ma”
Tiến trình thây ma hầu như không sử dụng chút tài nguyên nào từ máy
tính của bạn (hầu như bởi vì chúng chỉ chiếm một chút xíu dung lượng để
lưu mô tả tiến trình). Tuy nhiên, mỗi tiến trình trong Linux đều được
gán một mã số (PID). Tiến trình thây ma tuy là tiến trình chết nhưng vẫn
đươc coi là một tiến trình và vẫn chiếm 1 PID. Linux có số lượng PID
hữu hạn (ví dụ bản 32-bit có 32767 PID). Nếu tiến trình thây ma bị ứ
đọng lại bộ nhớ quá nhiều – ví dụ một phần mềm dành cho máy chủ được lập
trình ẩu, toàn bộ PID có thể bị chiếm hết trong một thời gian rất ngắn
và không một tiến trình nào có thể bắt đầu được nữa.
Tuy nhiên, nếu chỉ có vài tiến trình thây ma sẽ không gây hại gì cho máy tính bạn.
Cách dọn dẹp tiến trình thây ma.
Như đã nói ở trên, bạn không thể “giết” tiến trình thây ma được vì
bản chất chúng đã “chết” rồi. Cần nhớ rằng bạn không cần phải dọn dẹp
tiến trình thây ma trừ khi chúng tràn ngập bộ nhớ của bạn, một cài cái
sẽ không gây hại.
Cách thứ nhất là gửi tín hiệu SIGCHLD đến tiến trình cha mẹ. Tín
hiệu này sẽ ra lệnh cho tiến trình cha mẹ thực hiện chức năng wait() và
dọn sạch những “đứa con” đó. Gửi tín hiệu với lệnh kill, thay thế pid
bằng ID của tiến trình cha mẹ:
kill -s SIGCHLD pid
Tuy nhiên, nếu các tiến trình cha mẹ không được lập trình kỹ lưỡng,
nó thậm chí sẽ lờ đi tín hiệu SIGCHLD và câu lệnh trên là vô ích, bạn
sẽ phải tự mình “kill” tiến trình cha mẹ. Khi một tiến trình tạo ra tiến
trình thây ma bị giết, tiến trình với tên init sẽ thừa kế lại những
tiến trình thây ma và trở thành tiến trình cha mẹ mới (init là tiến
trình đầu tiên khởi động khi Linux khởi động, có PID là 1), sau đó init
sẽ thực hiện định kỳ chức năng wait() để dọn dẹp. Bạn có thể khởi động
lại tiến trình cha mẹ sau khi tắt chúng đi.
Còn nếu tiến trình cha mẹ lại tiếp tục sinh ra tiến trình thây ma,
bạn sẽ cần biện pháp khác. Ví dụ thay vì gọi wait() định kỳ, bạn sẽ phải
gọi Wait() theo nhu cầu. Nếu tiến trình thây ma vẫn tiếp tục được tạo
ra dù bạn đã thử nhiều phương pháp, lúc này bạn sẽ cần gửi báo cáo cho
nhà sản xuất phần mềm.
No comments:
Post a Comment