0
#include<stdio.h>
#include<sys/types.h>
int main()
{
   pid_t pid;
   if((pid=vfork())<0)
    {
            perror("FORK ERROR");
            exit(1);
    }
    if(pid==0)
    {
            printf("[CHILD] child id : %d\n" , pid);
            _exit(1);
    }
    else
    {
            printf("[PARENT] process id : %d\n" , pid);
            exit(1);
    }

}

上記のプログラムは、vforkを使用してプロセスを作成します。したがって、アドレス空間は親と子の間で共有されます。これは、pid変数のコピーが1つしかないことを意味します。しかし、子のpid変数を出力すると、0になります。親の同じpid変数は、子のプロセスIDを示します。pid変数のコピーが1つしかない場合、これはどのように可能になりますか。

4

2 に答える 2

3

vforkだけで実装されていない実数があると仮定するとfork、このプログラムは深刻な未定義の動作を引き起こします。printf子プロセス内の は、親プロセスのアドレス空間内の同じFILEオブジェクト ( stdout) を変更し、親に対して無効な状態のままにする可能性があります。実際には機能する可能性がありますが、機能する場合は、変更しないと信頼できない実装の詳細の結果です。後で安全に実行できる唯一の操作はvfork、関数_exitexecファミリーです。

それがどのように機能するか(printf問題のモジュール)についてvforkは、子が終了するまで親プロセスを一時停止するためvfork、親に戻ると、子はすでに終了しており、新しい戻り値は古いものと同じ場所に保存できます子に保存されます。

于 2012-09-04T22:41:24.127 に答える
0

親は子の後に vfork() から戻るため、pid は「正しい」値で上書きされます。

カーネル ソース ツリーで、kernel/fork.c

関数 do_fork() で

 do_fork()
 {
 ......
 if (clone_flags & CLONE_VFORK) {
                    p->vfork_done = &vfork;
                    init_completion(&vfork);
                    get_task_struct(p);
            }

            wake_up_new_task(p);

            /* forking complete and child started to run, tell ptracer */
            if (unlikely(trace))
                    ptrace_event(trace, nr);

            if (clone_flags & CLONE_VFORK) {
                    if (!wait_for_vfork_done(p, &vfork))
                            ptrace_event(PTRACE_EVENT_VFORK_DONE, nr);
  .....
     return nr; // pid of the child process.

}

wait_for_vfork_doneへの呼び出しを確認できます。親はここで vfork が戻るのを待っています。子が終了すると、親はここから再開します。子 pid はここから返されます。したがって、同じ pid 変数は、親と子で異なる値を与えます。

于 2012-09-04T22:36:11.993 に答える