我对以下代码的输出感到困惑。
#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系统编程。
答案 0 :(得分:2)
当孩子们到达fprintf()
时,父进程可能已经退出,导致子进程被重新分配给init(具有PID 1)。
在sleep(1)
之前添加return 0
可能会解决此问题。
答案 1 :(得分:0)
调用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()
返回错误指示或在父进程中时,已发布的代码将退出循环。
另一方面,在孩子的过程中,孩子绕着圈子试图创造一个孩子。子。
父母应该创建所有孩子并等待孩子在父退出之前完成/退出。
(waitpid()
是父母等待孩子的好方法)
注意:在退出孩子之前杀死孩子的父母可能导致三种情况中的任何一种(取决于特定的OS)孩子变成僵尸或孩子成为过程1的孩子或孩子得到信号并退出
这是一个如何编写代码的示例:
#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