10

pidXがプロセスグループリーダーであり、X終了したが、プロセスグループ内の他のプロセスは(Xpgidとして)実行されたままであるとします。XLinuxは、値がpidとして新しいプロセスに割り当てられるのを防ぎますか?

POSIXが許可する障害状態のためにこれを尋ねますsetsid

[EPERM]呼び出し元のプロセスがすでにプロセスグループリーダーであるか、呼び出し元のプロセス以外のプロセスのプロセスグループIDが呼び出し元のプロセスのプロセスIDと一致しています。

このエラーは、「ランダムに」トリガーされるプロセスグループ(つまりシェル)を使用するコードの回復不能な状態のようであり、さらに厄介なものになります。健全なレベルの品質を目指す実装ではX、まだpgidとして使用されている間は、pidとしての再割り当てを回避できると思いますが、これはどこにも文書化されていません。

4

2 に答える 2

6

フォークが保証するので、問題ありません:

子プロセスIDも、アクティブなプロセスグループIDと一致してはなりません。

そして、それforkが新しいプロセスを作成する唯一の方法です。

于 2011-07-22T03:23:34.380 に答える
5

Nemoは、POSIXがfork()既存のPGIDをPIDとして再利用しないことを保証していることは正しいです。ただし、話にはまだまだあります。

プロセスグループ、およびプロセスグループリーダーも、を使用して変更できますsetpgid()。次のサンプルコードにより、現在のプロセスのPIDに等しいプロセスグループが存在しますが、現在のプロセスは含まれていません。

#define _XOPEN_SOURCE 500
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
#include <signal.h>

int main()
{
    pid_t pgrp_orig;
    pid_t child;
    int status;

    /* Fork so that we are not a process group leader */
    if (fork()) {
        /* Grandparent process */
        wait(&status);
        return 0;
    }

    /* Record our original process group, then start a new one */
    pgrp_orig = getpgrp();
    if (setpgid(0, 0))
        perror("setpgid");

    child = fork();

    if (!child) {
        /* Child process */
        pause();
        return 0;
    }

    /* Switch back to original process group.  Child remains in the new one */
    if (setpgid(0, pgrp_orig))
        perror("setpgid");

    printf("Parent pid=%ld, pgid=%ld\n", (long)getpid(), (long)getpgrp());
    printf("Child pid=%ld, pgid=%ld\n", (long)child, (long)getpgid(child));

    /* Wake child up to finish up */
    kill(child, SIGUSR1);
    wait(&status);

    return 0;
}

子が終了する前に親プロセスがここを呼び出そうとすると、setsid()要求した失敗条件がトリガーされることに注意してください。

ただし、発生する可能性のある許容可能な遷移の制限によりsetpgid()、これにより、心配している種類のランダムな障害が発生することはありません。破損は単一のセッションに限定されます。

于 2011-07-22T04:36:37.130 に答える