UNIXプログラミングを学ぼうとしているときに、fork()に関する質問に遭遇しました。 fork()が現在実行中のプロセスと同じプロセスを作成することを理解していますが、それはどこから始まりますか?たとえば、コードがある場合
_int main (int argc, char **argv)
{
int retval;
printf ("This is most definitely the parent process\n");
fflush (stdout);
retval = fork ();
printf ("Which process printed this?\n");
return (EXIT_SUCCESS);
}
_
出力は次のとおりです。
これは間違いなく親プロセスです
これを印刷したプロセスはどれですか?
これを印刷したプロセスはどれですか?
私はfork()
が同じプロセスを作成すると思ったので、そのプログラムでは最初にfork()
呼び出しが再帰的に永久に呼び出されると思いました。 fork()
の呼び出し後に、fork()
から作成された新しいプロセスが開始されると思いますか?
親プロセスと子プロセスを区別するために次のコードを追加すると、
_if (child_pid = fork ()) printf ("This is the parent, child pid is %d\n", child_pid);
else printf ("This is the child, pid is %d\n",getpid ());
_
fork()呼び出しの後、子プロセスはどこで実行を開始しますか?
新しいプロセスはfork()
呼び出し内で作成され、親のようにそこから戻ることから始まります。 fork()
からの戻り値(retval
に保存したもの)は次のようになります。
テストコードは正しく動作します。 fork()
からの戻り値をchild_pid
に格納し、if
を使用して0かどうかを確認します(エラーの確認は行いません)
Fork()が同じプロセスを作成すると思ったので、最初は、そのプログラムでは、fork()呼び出しが再帰的に永久に呼び出されると思いました。 fork()から作成された新しいプロセスは、fork()呼び出しの後に開始されると思いますか?
はい。行に番号を付けましょう:
int main (int argc, char **argv)
{
int retval; /* 1 */
printf ("This is most definitely the parent process\n"); /* 2 */
fflush (stdout); /* 3 */
retval = fork (); /* 4 */
printf ("Which process printed this?\n"); /* 5 */
return (EXIT_SUCCESS); /* 6 */
}
実行フローは次のとおりです。
caller process fork() → ...
↘
original program exec() → 2 → 3 → 4 → 5 → 6
↘
forked program 5 → 6
...受け取った出力を正確に説明します。
元のプログラムと分岐したプログラムの動作が異なる可能性があることを知りたい場合は、それらが必ず同じコードを共有しているため、 Michael Mrozekの回答を参照してください。
これに対する本当の解決策は
switch (fork()) {
case -1 :
fprintf (stderr, "fork failed (%s)\n", strerror(errno));
break;
case 0 : // child process comes here
break;
default : // parent process
break;
}
// all continue here