web-dev-qa-db-ja.com

ゾンビプロセスの数に上限はありますか?

以前はHP-UXシステムで作業していましたが、古い管理者から、システムで使用できるゾンビプロセスの数には上限があると言われました。1024と思います。

  • これは難しい事実の天井ですか?プロセスをいくつでも持つことができるかのように、ゾンビをいくつでも持つことができると思います...?
  • ディストリビューションごとに値が異なりますか?
  • 上限に達して別のゾンビを作成しようとするとどうなりますか?
17

HP-UXを利用できません。また、HP-UXの大ファンになったことがありません。

Linuxでは、子プロセスの数にプロセスごとまたはユーザーごとの制限があるようです。 limit Zshビルトインでそれを見ることができます(bashの_ulimit -u_に類似しているようです):

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

それはArch Linuxラップトップです。

私はその制限をテストするための小さなプログラムを書きました:

_#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;
}
_

wait(2)を十分な回数呼び出して、すべてのゾンビを「収集」することは驚くほど困難でした。また、受信したSIGCHLDシグナルの数は、フォークされた子プロセスの数と同じになることはありません。Linuxカーネルは、終了した子プロセスの数に対して1 SIGCHLDを送信することがあります。

とにかく、私のArch Linuxラップトップでは、16088の子プロセスがフォークされます。これは、プログラムがシグナルハンドラーでwait(2)システムコールを実行しないため、ゾンビの数でなければなりません。

Slackware 12サーバーでは、_maxproc 6079_の値と厳密に一致する6076個の子プロセスを取得します。私のユーザーIDには、sshdとZshの2つのプロセスが実行されています。上記のプログラムの最初の非ゾンビインスタンスとともに、6079になります。

fork(2)システムコールは、「リソースが一時的に利用できません」というエラーで失敗します。どのリソースが利用できないかについての他の証拠は見当たりません。 2つの異なるxtermでプログラムを同時に実行すると、多少異なる数値が得られますが、1つのxtermで実行する場合と同じ数になります。プロセステーブルエントリ、またはスワップまたはシステム全体のリソースであり、単なる任意の制限ではないことを想定しています。

現在、他に試してみるものはありません。

11
Bruce Ediger

HP-UXの制限が何なのかわかりません。ただし、論理的な実装では、最大サイズのプロセステーブルを作成することをお伝えします。プロセステーブルエントリの総数は、理論的にはプロセスIDの範囲によって制限されますが、ほとんどの実装にはテーブルのサイズ制限があり、最大値ははるかに小さくなります。ほとんどのUNIXバリアントには、プロセス数にもユーザーごとの制限があります。 bashでulimit -uを実行すると、制限を確認できます。

UNIXシステムでは、プロセスID(実際のプロセスとゾンビを含む)の数ではなく、ゾンビに個別の制限があるとは思いません。したがって、プロセスが停止してゾンビになっても、制限には影響しません。リソース(プロセステーブルのエントリ)は、プロセスがフォークしたときに割り当てられ、プロセスが刈り取られたときに解放されます。

プロセスをいくつでも持つことができるかのように、ゾンビをいくつでも持つことができると思います...?

ゾンビプロセスは、最終的にはプロセス(特別な状態)であり、ゾンビプロセスはregularプロセスの場合と同様に、プロセステーブルの可用性とサイズに制限されます。

ディストリビューションごとに異なる値ですか?

確かに、他の多くのパラメータと同じように。特定のサイズで中継したり、多くのゾンビプロセスを保持するのに十分な大きさである場合は中継しないでください。ゾンビが多すぎる場合、最終的にはいっぱいになるため、解決策は大きなテーブルではありません。ゾンビプロセス自体は悪いことではありませんが、蓄積されたゾンビプロセスが多すぎることは、そのようなゾンビプロセスを許可している「不適切に動作する」プログラムを示しています。

上限に達して別のゾンビを作成しようとするとどうなりますか?

プロセステーブルが通常のプロセスとゾンビプロセスでいっぱいになると、システムに十分なリソース(メモリ、プロセッサなど)があっても、新しい-通常のプロセスを作成できなくなります。不足している唯一のリソースは、プロセステーブルの単一のエントリです。既に実行中のプログラム(「正常に動作する」プログラムであっても)は、サブプロセスを作成する必要があるときに失敗し始めます。新しいプログラムを開始できず、単一のコマンドを実行しても失敗します。

2