2012-06-06 33 views
17

私はいくつかのCを学び始めていますし、フォークを勉強している間、私は予期しない結果を得ました。少なくとも私にとっては。Fork()を使用して子プロセスを2つだけ作成する方法

親から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 ..."は、パイプで通信する2つの子プロセスと待機する親に対して1を出力します。

エラーがどこにあるかわかりますか?

+1

'フォーク(2)'の両方の非常にシンプルとUNIX APIで最も誤解コールの一つです。 「関連する」サイドバーを見てください。親と子の間ではなく、2人の子供の間でコミュニケーションが必要な特別な理由はありますか? – dmckee

+0

fork()コールではなぜpid == 0をチェックしていますか?どちらが親であり、どちらが子供であるかをどのように知ることができますか? – TwilightSparkleTheGeek

+1

@TwilightSparkleTheGeek 'man fork'の状態: 戻り値 成功すると、子プロセスのPIDが親に返され、子に 0が返されます。失敗した場合、親に-1が返され、 子プロセスが作成されず、errnoが適切に設定されます。 – mimoralea

答えて

30
pid = fork(); #1 
pidb = fork(); #2 

私たちは、親プロセスIDが100であると仮定しましょう、最初のフォークは今、別のプロセス101を作成し、両方の100 & 101は、#1の後に実行を継続するので、彼らは、第二のフォークを実行します。 pid100は#2に到達し、別のプロセス102を生成する.pid101は#2に到達して別のプロセス103を生成する。したがって、4つのプロセスが終了する。

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

+3

これは間違いなく機能します。しかし、代わりにswitch文を使うことをお勧めします。 fork関数は-1を返し、switch文の中にcase -1を指定してこのエラーを処理できます。 – sj755

+0

私は親がelseステートメントの後ろだと思った。 if文の親はなぜですか?よくわかりません。 – TwilightSparkleTheGeek

+1

forkは、子ではなく、親ではなく0を返します。親プロセスでは、作成した子プロセスのPIDが返されます。これはより便利です。 – mimoralea

3

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

あなたのケースでは、最初のフォークステートメントが子プロセスを作成したということでした。だから、現在のところ親はP1、子はC1です。

ここで、P1とC1の両方が2番目のfork文に遭遇します。親は別の子(c2)を作成しますが、子でもc1が子プロセス(c3)を作成します。実際にはP1、C1、C2、C3を持っているので、4つのprint文の出力があります。

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

13

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

あなただけの、2つのプロセスを作成する場合:

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

あなたは、このようなn個の子プロセスを作成することができます。

for (i = 0; i < n; ++i) { 
    pid = fork(); 
    if (pid) { 
     continue; 
    } else if (pid == 0) { 
     break; 
    } else { 
     printf("fork error\n"); 
     exit(1); 
    } 
} 
0

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

0

子プロセス内に子プロセスを作成できます。この方法で、元の親プロセスを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! 
関連する問題