Có giới hạn trên cho số lượng quá trình zombie bạn có thể có không?


17

Tôi đã từng làm việc với một hệ thống HP-UX và quản trị viên cũ nói với tôi rằng có giới hạn trên về số lượng quy trình zombie bạn có thể có trên hệ thống, tôi tin là 1024.

  • Đây có phải là một trần thực tế khó khăn? Tôi nghĩ rằng bạn có thể có bất kỳ số lượng zombie như thể bạn có thể có bất kỳ số lượng quá trình ...?
  • Có giá trị khác nhau từ distro đến distro?
  • Điều gì xảy ra nếu chúng ta đạt đến giới hạn trên và cố gắng tạo ra một zombie khác?

1
Theo bài viết trên blog này , giới hạn duy nhất trên Linux là số lượng PID, chỉ ảnh hưởng ngẫu nhiên đến zombie.
bahamat

2
Cả hai câu trả lời dưới đây đều đề cập ulimit -u. Tôi đã bối rối trong một thời gian khi man ulimittôi có một thói quen C mà không đề cập đến -u. Trên thực tế, ulimit được đề cập là một công cụ bash tích hợp và nó được mô tả trong trang bash.
Emanuel Berg

Câu trả lời:


11

Tôi không có sẵn HP-UX và tôi chưa bao giờ là một fan hâm mộ HP-UX lớn.

Dường như trên Linux, giới hạn cho mỗi quá trình hoặc có thể cho mỗi người dùng về số lượng quy trình con tồn tại. Bạn có thể thấy nó với limitZsh tích hợp (dường như tương tự như ulimit -utrong bash):

1002 % limit
cputime         unlimited
filesize        unlimited
datasize        unlimited
stacksize       8MB
coredumpsize    0kB
memoryuse       unlimited
maxproc         16136
  ...

Đó là trên một máy tính xách tay Arch linux.

Tôi đã viết một chương trình nhỏ để kiểm tra giới hạn đó:

#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>

volatile int sigchld_cnt = 0;

voida
sigchld_hdlr(int signo)
{
        ++sigchld_cnt;
}

int
main(int ac, char **av)
{
        int looping = 1;
        int child_cnt = 0;
        int status;

        signal(SIGCHLD, sigchld_hdlr);

        printf("Parent PID %d\n", getpid());

        while (looping)
        {
                switch (fork())
                {
                case 0:
                        _exit(0);
                        break;
                case -1:
                        fprintf(stderr, "Problem with fork(), %d children: %s\n",
                                child_cnt, strerror(errno));
                        looping = 0;
                        break;
                default:
                        ++child_cnt;
                        break;
                }
        }

        fprintf(stderr, "Sleeping, forked %d child processes\n", child_cnt);
        fprintf(stderr, "Received %d sigchild\n", sigchld_cnt);
        sleep(10);

        looping = 1;
        do {
                int x = wait(&status);

                if (x != -1)
                        --child_cnt;
                else if (errno != EINTR) {
                        fprintf(stderr, "wait() problem %d children left: \%s\n",
                                child_cnt, strerror(errno));
                        looping = 0;
                }
        } while (looping);

        printf("%d children left, %d SIGCHLD\n", child_cnt, sigchld_cnt);

        return 0;
}

Thật khó để "thu thập" tất cả các thây ma bằng cách gọi wait(2)đủ số lần. Ngoài ra, số lượng tín hiệu SIGCHLD nhận được không bao giờ bằng số lượng tiến trình con được chia rẽ: Tôi tin rằng nhân linux đôi khi gửi 1 SIGCHLD cho một số tiến trình con đã thoát.

Dù sao, trên máy tính xách tay Arch linux của tôi, tôi có 16088 tiến trình con được chia rẽ và đó phải là số lượng zombie, vì chương trình không thực hiện wait(2)các cuộc gọi hệ thống trong trình xử lý tín hiệu.

Trên máy chủ Slackware 12 của tôi, tôi nhận được 6076 tiến trình con, rất khớp với giá trị của maxproc 6079. ID người dùng của tôi có 2 tiến trình khác đang chạy sshdvà Zsh. Cùng với phiên bản đầu tiên, không phải zombie của chương trình trên tạo ra 6079.

Cuộc fork(2)gọi hệ thống không thành công với lỗi "Tài nguyên tạm thời không khả dụng". Tôi không thấy bất kỳ bằng chứng nào khác về tài nguyên nào không có sẵn. Tôi nhận được một số số khác nhau nếu tôi chạy chương trình của mình đồng thời ở 2 xterms khác nhau, nhưng chúng cộng với cùng một số như thể tôi chạy nó trong một xterm. Tôi giả sử đó là quá trình nhập bảng, hoặc trao đổi hoặc một số tài nguyên trên toàn hệ thống và không chỉ là giới hạn tùy ý.

Tôi không có gì khác để chạy thử ngay bây giờ.


4

Tôi không biết giới hạn của HP-UX là gì. Tuy nhiên tôi có thể nói với bạn rằng việc triển khai logic là có một bảng quy trình với kích thước tối đa. Tổng số mục của bảng quy trình bị giới hạn về mặt lý thuyết bởi phạm vi ID quy trình, nhưng hầu hết các triển khai đều có giới hạn kích thước cho bảng mang lại mức tối đa nhỏ hơn nhiều. Hầu hết các biến thể unix cũng có giới hạn cho mỗi người dùng về số lượng quá trình; bạn có thể thấy giới hạn bằng cách chạy ulimit -utrong bash.

Tôi không mong đợi một hệ thống unix có giới hạn riêng cho zombie, hơn là về số ID tiến trình (bao gồm các quy trình thực tế cũng như zombie). Vì vậy, khi một quá trình chết đi và trở thành một thây ma, điều đó không ảnh hưởng đến giới hạn: tài nguyên (mục nhập trong bảng quy trình) được phân bổ khi một quá trình rẽ nhánh và giải phóng khi quá trình được gặt hái.


2

Tôi nghĩ rằng bạn có thể có bất kỳ số lượng zombie như thể bạn có thể có bất kỳ số lượng quá trình ...?

Một quy trình zombie cuối cùng là một quy trình - trong một trạng thái đặc biệt - sau đó các quy trình zombie bị giới hạn về tính khả dụng và kích thước của bảng quy trình, như đối với các quy trình thông thường .

Có giá trị khác nhau từ distro đến distro?

Chắc chắn, như nhiều thông số khác. Bạn không nên chuyển tiếp trên một kích thước cụ thể, hoặc nếu nó đủ lớn để chứa nhiều quá trình zombie. Nếu bạn nhận được quá nhiều zombie, giải pháp không phải là một cái bàn lớn, vì cuối cùng nó sẽ trở nên đầy đủ. Bản thân một quá trình zombie không phải là xấu, nhưng có quá nhiều quá trình zombie tích lũy là một dấu hiệu của một chương trình "hành xử xấu" cho phép quá trình zombie như vậy.

Điều gì xảy ra nếu chúng ta đạt đến giới hạn trên và cố gắng tạo ra một zombie khác?

Khi bảng quy trình đầy đủ - thông thường và quy trình zombie-, không có quy trình mới nào có thể được tạo, ngay cả khi hệ thống có đủ tài nguyên -memory, bộ xử lý, v.v.-. Tài nguyên thiếu duy nhất chỉ là một mục trong bảng quy trình. Đã chạy các chương trình - cả những "hành vi tốt" đó - sẽ bắt đầu thất bại khi chúng yêu cầu tạo một quy trình phụ. Các chương trình mới không thể khởi động và thậm chí chạy các lệnh đơn lẻ sẽ thất bại.


Even running single commands would fail.-> đó là một tác động lớn.
Shiplu Mokaddim
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.