Fatmawati Achmad Zaenuri / Shutterstock

Các chương trình được viết kém hoặc hoạt động kém có thể rời khỏi quy trình zombie ẩn bên trong máy tính Linux của bạn. Tìm hiểu cách tạo ra thây ma và cuối cùng bạn có thể đặt chúng nghỉ ngơi như thế nào.

Cách các trạng thái xử lý hoạt động trên Linux

Tất nhiên, Linux phải theo dõi tất cả các ứng dụng và daemon đang chạy trên máy tính của bạn. Một trong những cách nó thực hiện điều này là duy trì bảng tiến trình. Đây là danh sách các cấu trúc trong bộ nhớ hạt nhân. Mỗi quy trình có một mục trong danh sách này chứa một số thông tin về nó.

Không có nhiều thứ trong mỗi cấu trúc bảng quy trình. Họ nắm giữ xử lý ID, một số mục dữ liệu khác và một con trỏ đến khối điều khiển quy trình (PCB) cho quy trình đó.

Đó là PCB chứa nhiều chi tiết mà Linux cần tra cứu hoặc thiết lập cho mỗi quá trình. PCB cũng được cập nhật khi một quá trình được tạo ra, có thời gian xử lý và cuối cùng bị phá hủy.

PCB của Linux chứa hơn 95 trường. Nó được xác định như một cấu trúc được gọi là task_struct.hvà dài hơn 700 dòng. PCB chứa các loại thông tin sau:

  • Trạng thái quy trình: Các trạng thái được mô tả dưới đây.
  • Số quy trình: Định danh duy nhất của nó trong hệ điều hành.
  • Bộ đếm chương trình: Khi tiến trình này được cấp quyền truy cập tiếp theo vào CPU, hệ thống sẽ sử dụng địa chỉ này để tìm lệnh tiếp theo của tiến trình cần được thực thi.
  • Đăng ký: Danh sách các thanh ghi CPU được sử dụng bởi quá trình này. Danh sách có thể chứa bộ tích lũy, thanh ghi chỉ mục và con trỏ ngăn xếp.
  • Mở danh sách tệp: Các tệp được liên kết với quá trình này.
  • Thông tin lập lịch CPU: Được sử dụng để xác định tần suất và bao lâu, thời gian xử lý của CPU được trao cho quá trình này. Mức độ ưu tiên của quá trình, con trỏ đến hàng đợi lập lịch và các thông số lập lịch khác phải được ghi lại trong PCB.
  • Thông tin quản lý bộ nhớ: Thông tin chi tiết về bộ nhớ mà quá trình này đang sử dụng, chẳng hạn như địa chỉ bắt đầu và địa chỉ kết thúc của bộ nhớ tiến trình và con trỏ đến các trang bộ nhớ.
  • Thông tin trạng thái I / O: Bất kỳ thiết bị đầu vào hoặc đầu ra nào được sử dụng bởi quy trình.

Các Process State có thể là bất kỳ điều nào sau đây:

  • NS: Một quá trình đang chạy hoặc có thể chạy được. Đang chạy có nghĩa là nhận chu kỳ CPU và thực thi. Một tiến trình có thể chạy đã sẵn sàng để chạy và đang chờ một khe cắm CPU.
  • NS: Một quá trình ngủ. Quá trình đang đợi một hành động hoàn thành, chẳng hạn như hoạt động đầu vào hoặc đầu ra, hoặc tài nguyên sẵn có.
  • NS: Quá trình này ở trạng thái ngủ liên tục. Nó sử dụng một cuộc gọi hệ thống chặn và không thể tiếp tục cho đến khi các cuộc gọi hệ thống hoàn tất. Không giống như Sleep trạng thái, một quy trình ở trạng thái này sẽ không phản hồi lại các tín hiệu cho đến khi hoàn thành lệnh gọi hệ thống và quá trình thực thi đã quay trở lại quy trình.
  • NS: Quá trình đã kết thúc (dừng) vì nó nhận được SIGSTOP dấu hiệu. Nó sẽ chỉ trả lời đến SIGKILL hoặc SIGCONT tín hiệu, có thể giết chết quá trình hoặc hướng dẫn nó tiếp tục, tương ứng. Đây là chuyện gì đang xảy ra khi bạn hoán đổi từ vấn đề xung quanh (fg) đến lai lịch (bg) các nhiệm vụ.
  • Z: Một quá trình Zombie. Khi một quá trình hoàn thành, nó không chỉ biến mất. Nó giải phóng bất kỳ bộ nhớ nào mà nó đang sử dụng và xóa chính nó khỏi bộ nhớ, nhưng mục nhập của nó trong bảng quy trình và PCB vẫn còn. Trạng thái của nó được đặt thành EXIT_ZOMBIEvà quy trình mẹ của nó được thông báo (bởi SIGCHLD tín hiệu) rằng quá trình con đã kết thúc.
  Cách tự động ẩn thanh tác vụ Windows

Trong trạng thái Zombie, tiến trình mẹ gọi một trong các wait() họ của các chức năng khi tiến trình con được tạo. Sau đó, nó chờ đợi sự thay đổi trạng thái trong tiến trình con. Quá trình con có bị dừng, tiếp tục hay bị chết bởi một tín hiệu nào không? Nó đã kết thúc bằng cách chạy qua quá trình hoàn thành tự nhiên của mã của nó chưa?

Nếu trạng thái thay đổi có nghĩa là tiến trình con đã ngừng chạy, mã thoát của nó sẽ được đọc. Sau đó, PCB con bị phá hủy và mục nhập của nó trong bảng quy trình bị xóa. Lý tưởng nhất, tất cả điều này xảy ra trong chớp mắt và các quá trình ở trạng thái zombie không tồn tại trong thời gian dài.

CÓ LIÊN QUAN: Cách chạy và kiểm soát các quy trình nền trên Linux

Nguyên nhân nào gây ra quá trình Zombie trên Linux?

Một quy trình mẹ được viết kém có thể không gọi wait() khi tiến trình con được tạo. Điều này có nghĩa là không có gì đang theo dõi các thay đổi trạng thái trong quá trình con và SIGCHLD tín hiệu sẽ bị bỏ qua. Hoặc, có lẽ một ứng dụng khác đang ảnh hưởng đến việc thực thi quy trình mẹ, do lập trình kém hoặc có mục đích xấu.

Tuy nhiên, nếu quy trình mẹ không theo dõi các thay đổi trạng thái trong quy trình con, thì quy trình quản lý hệ thống thích hợp sẽ không xảy ra. PCB và mục nhập trong bảng quy trình sẽ không bị xóa khi quy trình con kết thúc. Điều này dẫn đến trạng thái zombie không bao giờ bị xóa khỏi PCB.

Zombies có sử dụng một chút bộ nhớ, nhưng chúng thường không gây ra vấn đề gì. Mục nhập trong bảng quy trình là nhỏ, nhưng, cho đến khi nó được phát hành, ID quy trình không thể được sử dụng lại. Trên hệ điều hành 64-bit, điều đó không có khả năng gây ra bất kỳ sự cố nào vì PCB lớn hơn nhiều so với mục nhập bảng quy trình.

Có thể hình dung được một số lượng lớn zombie có thể ảnh hưởng đến dung lượng bộ nhớ còn trống cho các quá trình khác. Tuy nhiên, nếu bạn có nhiều thây ma như vậy, bạn đã gặp sự cố nghiêm trọng với ứng dụng mẹ hoặc lỗi hệ điều hành.

  Điểm của ổ cứng không dây là gì và tôi có cần ổ cứng không?

Làm thế nào để loại bỏ các quá trình Zombie

Bạn không thể giết một quá trình zombie vì nó đã chết. Nó sẽ không phản hồi bất kỳ tín hiệu nào vì nó đã bị xóa khỏi bộ nhớ — không có nơi nào để gửi SIGKILL dấu hiệu. Bạn có thể thử gửi SIGCHLD báo hiệu cho tiến trình mẹ, nhưng nếu nó không hoạt động khi quá trình con kết thúc, nó cũng không hoạt động ngay bây giờ.

Giải pháp đáng tin cậy duy nhất là giết tiến trình mẹ. Khi nó kết thúc, các tiến trình con của nó được kế thừa bởi init process, là process đầu tiên chạy trong hệ thống Linux (process ID của nó là 1).

Các init Process thường xuyên thực hiện dọn dẹp zombie cần thiết, vì vậy để tiêu diệt chúng, bạn chỉ cần giết tiến trình đã tạo ra chúng. Các top là một cách thuận tiện để xem bạn có bất kỳ thây ma nào không.

Nhập nội dung sau:

top

Hệ thống này có tám quy trình zombie. chúng tôi có thể liệt kê những bằng cách sử dụng ps và đưa nó vào egrep. Một lần nữa, các quy trình zombie có cờ trạng thái là Z, và bạn cũng sẽ thường thấy defunct.

Nhập nội dung sau:

ps aux | egrep “Z|defunct”

Các quá trình zombie được liệt kê.

Đây là một cách đơn giản hơn để khám phá ID quá trình của zombie hơn là cuộn qua lại top. Chúng tôi cũng thấy rằng một ứng dụng được gọi là badprg sinh ra những thây ma này.

ID tiến trình của zombie đầu tiên là 7641, nhưng chúng ta cần tìm ID tiến trình của tiến trình mẹ của nó. Chúng ta có thể làm như vậy bằng cách sử dụng ps lần nữa. Sử dụng tốt tùy chọn đầu ra (-o) nói ps để chỉ hiển thị ID quy trình cha mẹ và sau đó chuyển nó với ppid=.

Quá trình chúng tôi muốn tìm sẽ được chỉ ra bằng cách sử dụng -p (process) tùy chọn, và sau đó chuyển ID tiến trình zombies.

Do đó, chúng tôi gõ lệnh sau để tra cứu thông tin quy trình cho quy trình 7641, nhưng nó sẽ chỉ báo cáo ID của quy trình mẹ:

ps -o ppid= -p 7641

Đã được thông báo rằng ID quy trình chính là 7636. Giờ đây, chúng tôi có thể tham chiếu chéo điều này bằng cách sử dụng ps một lần nữa.

Chúng tôi thấy điều này khớp với tên của quy trình mẹ trước đó. Để hủy tiến trình mẹ, hãy sử dụng tùy chọn SIGKILL với lệnh hủy như sau:

kill -SIGKILL 7636

Tùy thuộc vào chủ sở hữu của quy trình mẹ, bạn cũng có thể cần sử dụng sudo.

Zombies không đáng sợ…

… Trừ khi họ ở trong một đám đông lớn. Một số không có gì phải lo lắng và khởi động lại đơn giản sẽ xóa sạch chúng.

Tuy nhiên, nếu bạn nhận thấy rằng một ứng dụng hoặc quy trình luôn tạo ra các thây ma, đó là điều bạn nên xem xét. Rất có thể nó chỉ là một chương trình được viết cẩu thả, trong trường hợp đó, có lẽ có một phiên bản cập nhật để dọn dẹp đúng cách sau khi xử lý con của nó.