使用fork后父id returns 1
Parent id returns 1 after using fork
我对以下代码的输出感到困惑。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main (int argc, char *argv[]) {
pid_t childpid = 0;
int i, n;
if (argc != 2){ /* check for valid number of command-line arguments */
fprintf(stderr, "Usage: %s processes\n", argv[0]);
return 1;
}
n = atoi(argv[1]);
for (i = 1; i < n; i++)
if ((childpid = fork()))
break;
fprintf(stderr,"i:%d process ID:%ld parent ID:%ld child ID:%ld\n",
i, (long)getpid(), (long)getppid(), (long)childpid);
return 0;
}
在 运行 之后输出,命令参数 n = 3:
i:1 process ID:3662 parent ID:2658 child ID:3663
i:2 process ID:3663 parent ID:1 child ID:3664
i:3 process ID:3664 parent ID:1 child ID:0
我想知道为什么父 ID 总是 1,并且在我将最后一行代码更改为
printf 而不是 fprintf,父 ID 偶尔只包含 1。这是
教科书中的一个例子——Unix系统编程。
当子进程到达 fprintf()
时,父进程可能已经退出,导致子进程重新成为 init(PID 为 1)的父进程。
在 return 0
之前添加 sleep(1)
可能会解决这个问题。
调用fork()
时有3种返回值。
-1 when the `fork()` failed to create a child process
0 when the current process is the child
>0 when the current process is the parent.
当 fork()
返回错误指示或在 parent 进程中时,发布的代码正在退出循环。
否则,在 child 进程和 child 循环中尝试创建 childs' child.
parent 应该正在创建所有 children 并在 parent 退出之前等待 children 到 complete/exit。
(waitpid()
是 parent 等待 child 的好方法)
注意:在退出 child 之前杀死 child 的 parent 会导致三种情况之一(取决于具体的 OS) child 成为僵尸或 child 成为进程 1 的 child 或 child 收到信号并退出
这里有一个如何编写代码的例子:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int main (int argc, char *argv[])
{
int i, n;
if (argc != 2)
{ /* check for valid number of command-line arguments */
fprintf(stderr, "Usage: %s <Number of child processes to create>\n", argv[0]);
exit( EXIT_FAILURE );
}
// implied else, correct number of arguments
n = atoi(argv[1]);
pid_t childpid[n];
for (i = 0; i < n; i++)
{
switch( childpid[i] = fork() )
{
case -1:
// handle fork failure
perror( "fork failed" );
exit( EXIT_FAILURE );
break;
case 0:
// handle child
fprintf(stderr,
"i:%d CHILD process ID:%ld PARENT process ID:%ld\n",
i,
(long)getpid(),
(long)getppid());
exit( EXIT_SUCCESS );
break;
default:
// handle parent
fprintf(stderr,
"i:%d PARENT process ID:%ld CHILD process ID:%ld\n",
i,
(long)getpid(),
(long)childpid[i]);
break;
} // end switch
} // end for
for( i=0; i<n; i++ )
{
waitpid( childpid[i], NULL, 0 );
}
return 0;
} // end function: main
一个示例输出是:当命令行参数是 3
i:0 PARENT process ID:918 CHILD process ID:919
i:1 PARENT process ID:918 CHILD process ID:920
i:0 CHILD process ID:919 PARENT process ID:918
i:1 CHILD process ID:920 PARENT process ID:918
i:2 PARENT process ID:918 CHILD process ID:921
i:2 CHILD process ID:921 PARENT process ID:918
我对以下代码的输出感到困惑。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main (int argc, char *argv[]) {
pid_t childpid = 0;
int i, n;
if (argc != 2){ /* check for valid number of command-line arguments */
fprintf(stderr, "Usage: %s processes\n", argv[0]);
return 1;
}
n = atoi(argv[1]);
for (i = 1; i < n; i++)
if ((childpid = fork()))
break;
fprintf(stderr,"i:%d process ID:%ld parent ID:%ld child ID:%ld\n",
i, (long)getpid(), (long)getppid(), (long)childpid);
return 0;
}
在 运行 之后输出,命令参数 n = 3:
i:1 process ID:3662 parent ID:2658 child ID:3663
i:2 process ID:3663 parent ID:1 child ID:3664
i:3 process ID:3664 parent ID:1 child ID:0
我想知道为什么父 ID 总是 1,并且在我将最后一行代码更改为 printf 而不是 fprintf,父 ID 偶尔只包含 1。这是 教科书中的一个例子——Unix系统编程。
当子进程到达 fprintf()
时,父进程可能已经退出,导致子进程重新成为 init(PID 为 1)的父进程。
在 return 0
之前添加 sleep(1)
可能会解决这个问题。
调用fork()
时有3种返回值。
-1 when the `fork()` failed to create a child process
0 when the current process is the child
>0 when the current process is the parent.
当 fork()
返回错误指示或在 parent 进程中时,发布的代码正在退出循环。
否则,在 child 进程和 child 循环中尝试创建 childs' child.
parent 应该正在创建所有 children 并在 parent 退出之前等待 children 到 complete/exit。
(waitpid()
是 parent 等待 child 的好方法)
注意:在退出 child 之前杀死 child 的 parent 会导致三种情况之一(取决于具体的 OS) child 成为僵尸或 child 成为进程 1 的 child 或 child 收到信号并退出
这里有一个如何编写代码的例子:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int main (int argc, char *argv[])
{
int i, n;
if (argc != 2)
{ /* check for valid number of command-line arguments */
fprintf(stderr, "Usage: %s <Number of child processes to create>\n", argv[0]);
exit( EXIT_FAILURE );
}
// implied else, correct number of arguments
n = atoi(argv[1]);
pid_t childpid[n];
for (i = 0; i < n; i++)
{
switch( childpid[i] = fork() )
{
case -1:
// handle fork failure
perror( "fork failed" );
exit( EXIT_FAILURE );
break;
case 0:
// handle child
fprintf(stderr,
"i:%d CHILD process ID:%ld PARENT process ID:%ld\n",
i,
(long)getpid(),
(long)getppid());
exit( EXIT_SUCCESS );
break;
default:
// handle parent
fprintf(stderr,
"i:%d PARENT process ID:%ld CHILD process ID:%ld\n",
i,
(long)getpid(),
(long)childpid[i]);
break;
} // end switch
} // end for
for( i=0; i<n; i++ )
{
waitpid( childpid[i], NULL, 0 );
}
return 0;
} // end function: main
一个示例输出是:当命令行参数是 3
i:0 PARENT process ID:918 CHILD process ID:919
i:1 PARENT process ID:918 CHILD process ID:920
i:0 CHILD process ID:919 PARENT process ID:918
i:1 CHILD process ID:920 PARENT process ID:918
i:2 PARENT process ID:918 CHILD process ID:921
i:2 CHILD process ID:921 PARENT process ID:918