web-dev-qa-db-ja.com

Fork()を使用して2つの子プロセスのみを作成する方法は?

私はいくつかのCを学び始めており、フォークを勉強している間に、予期しない出力になった関数を待ちます。少なくとも私にとっては。

親から2つの子プロセスのみを作成する方法はありますか?

ここに私のコード:

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

int main ()
{
    /* Create the pipe */
    int fd [2];
    pipe(fd);

    pid_t pid;
    pid_t pidb;


    pid = fork ();
    pidb = fork ();

    if (pid < 0)
    {
        printf ("Fork Failed\n");
        return -1;
    }
    else if (pid == 0)
    {
        //printf("I'm the child\n");
    }
    else 
    {
        //printf("I'm the parent\n");
    }

    printf("I'm pid %d\n",getpid());

    return 0;
}

そして、これが私の出力です:

I'm pid 6763
I'm pid 6765
I'm pid 6764
I'm pid 6766

パイプ部分を無視してください、私はまだそこまで行っていません。私はただ2つの子プロセスを作成しようとしているので、3つの「I'm pid ...」は、待機する親に対して1つだけ、パイプ経由で通信する2つの子プロセスを出力することを期待しています。

私のエラーがどこにあるかがわかりましたら教えてください。

17
mimoralea
pid = fork (); #1
pidb = fork (); #2

親プロセスIDが100で、最初のフォークが別のプロセス101を作成するとします。100と101の両方が#1の後も実行を継続するので、2番目のフォークを実行します。 pid 100は#2に到達して別のプロセス102を作成します。pid101は#2に到達して別のプロセス103を作成します。したがって、4つのプロセスになります。

あなたがすべきことはこのようなものです。

if(fork()) # parent
    if(fork()) #parent
    else # child2
else #child1
31
tuxuday

Processを作成した後、戻り値を確認する必要があります。しない場合、seconde fork()は親プロセスと子プロセスの両方で実行されるため、4つのプロセスがあります。

2つの子プロセスを作成する場合は、次のようにします。

if (pid = fork()) {
    if (pid = fork()) {
        ;
    } 
} 

次のようにn個の子プロセスを作成できます。

for (i = 0; i < n; ++i) {
    pid = fork();
    if (pid > 0) {   /* I am the parent, create more children */
        continue;
    } else if (pid == 0) { /* I am a child, get to work */
        break;
    } else {
        printf("fork error\n");
        exit(1);
    }
}
13
Fei Xue

Forkステートメントが親によって実行されると、期待どおりに子プロセスが作成されます。子プロセスもforkステートメントを実行しますが、0を返しますが、親はpidを返します。 forkステートメントの後のすべてのコードは、親andの両方によって実行されます。

あなたのケースでは、最初のforkステートメントが子プロセスを作成していました。そのため、現在、1つの親P1と1つの子C1があります。

これで、P1とC1の両方が2番目のforkステートメントに遭遇します。親は期待どおりに別の子(c2)を作成しますが、子c1でも子プロセス(c3)を作成します。したがって、実際にはP1、C1、C2、およびC3があり、これが4つの印刷ステートメント出力を取得した理由です。

これについて考える良い方法は、各ノードがプロセスを表し、ルートノードが最上位の親であるツリーを使用することです。

3
rounak

子プロセス内に子プロセスを作成できます。これにより、元の親プロセスのコピーを2つ持つことができます。

int main (void) {
    pid_t pid, pid2;
    int status;

    pid = fork();

    if (pid == 0) { //child process
        pid2 = fork();
        int status2;

        if (pid2 == 0) { //child of child process
            printf("friends!\n");
        }
        else {
            printf("my ");
            fflush(stdout);
            wait(&status2);
        }
    }
    else { //parent process
        printf("Hello ");
        fflush(stdout);
        wait(&status);
    }

    return 0;
}

これにより、次が出力されます。

Hello my friends!
0
Rui Gonçalves

(pid <0)プロセスの作成が失敗したかのように値を確認できます。これは、子プロセスの作成が失敗したかどうかを示します。getpid()が親プロセスから使用される場合、forkは子プロセスのプロセスIDを返します。

0
nilesh