无法使用 getppid() 获得预期的 ID
cannot get expected id by using getppid()
我在做一个多进程的实践。我只是想查看一下父进程id,和我想象的不太一样。这是我的代码:
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/ipc.h>
#include <string.h>
#include <sys/sem.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
void child1()
{
//printf("we are child1..\n");
printf("my pid is:%d\n",getpid());
printf("I am child1..\n");
}
void child2()
{
//printf("we are child2..\n");
printf("my pid is:%d\n",getpid());
printf("I am child2.., my parent is:%d\n",getppid());
}
int main()
{
pid_t childpid[4];
int i;
printf("main pid is:%d\n",getpid());
for (i=0;i<2;i++)
{
childpid[i] = fork();
if (childpid[i]<0)
printf("fork fail..\n");
else if (childpid[i]==0)
{
childpid[i+2] = fork();
if (childpid[i+2] <0)
printf("fork inside fail..\n");
else if (childpid[i+2]==0)
child2();
else // this is parent process..
child1();
}
}
}
执行结果如下:
my pid is:3951
I am child1..
my pid is:3950
I am child1..
my pid is:3952
I am child2.., my parent is:1118
my pid is:3954
I am child1..
my pid is:3953
I am child2.., my parent is:1118
my pid is:3956
I am child1..
my pid is:3955
I am child2.., my parent is:1118
my pid is:3957
I am child2.., my parent is:1118
因为我的 child2 进程是在 process1 内部分叉的,我预计父 pid 可能是 like:3950。我的结果怎么来的 get:1118?
感谢您的帮助!
您的进程不会等待其子进程终止。最有可能的是,父进程已经终止并且子进程被重新设置。
当我 运行 逐字记录您的代码时(嗯,好的;我将 void
添加到每个空参数列表并使子函数成为 static
),然后我得到示例输出:
main pid is:46761
my pid is:46762
I am child1..
my pid is:46763
my pid is:46764
I am child1..
I am child2.., my parent is:46762
my pid is:46765
I am child2.., my parent is:1
my pid is:46766
I am child1..
my pid is:46768
my pid is:46767
I am child2.., my parent is:46766
I am child1..
my pid is:46769
I am child2.., my parent is:1
为了娱乐价值,我运行输出到一个管道得到:
main pid is:46770
main pid is:46770
my pid is:46773
I am child1..
main pid is:46770
my pid is:46772
I am child1..
main pid is:46770
my pid is:46775
I am child2.., my parent is:1
main pid is:46770
my pid is:46774
I am child2.., my parent is:46772
main pid is:46770
my pid is:46772
I am child1..
my pid is:46776
I am child1..
main pid is:46770
my pid is:46772
I am child1..
my pid is:46778
I am child2.., my parent is:1
main pid is:46770
my pid is:46774
I am child2.., my parent is:46772
my pid is:46777
I am child1..
main pid is:46770
my pid is:46774
I am child2.., my parent is:46772
my pid is:46779
I am child2.., my parent is:46777
有关该行为的解释,请参阅 printf()
anomaly after fork()
。
然后我对你的代码进行了稍微不同的检测,但核心逻辑没有改变:
#include <stdio.h>
#include <sys/wait.h>
#include <unistd.h>
static void child1(void)
{
printf("Child1: PID = %d, PPID = %d\n", (int)getpid(), (int)getppid());
}
static void child2(void)
{
printf("Child2: PID = %d, PPID = %d\n", (int)getpid(), (int)getppid());
}
int main(void)
{
pid_t childpid[4];
int i;
printf("main pid is:%d\n", getpid());
for (i = 0; i < 2; i++)
{
fflush(0);
childpid[i] = fork();
if (childpid[i] < 0)
printf("fork fail in PID %d\n", getpid());
else if (childpid[i] == 0)
{
childpid[i + 2] = fork();
if (childpid[i + 2] < 0)
printf("fork fail in PID %d\n", getpid());
else if (childpid[i + 2] == 0)
child2();
else
{
printf("child pid %d forked child %d\n", (int)getpid(), (int)childpid[i+2]);
child1();
}
}
else
printf("main pid %d forked child %d\n", (int)getpid(), (int)childpid[i]);
}
int status;
int corpse;
while ((corpse = wait(&status)) != -1)
printf("PID %d: child %d died with status %.4X\n", (int)getpid(), corpse, status);
printf("PID %d: finished\n", (int)getpid());
return getpid() % 256;
}
我确实添加了等待子进程死亡的代码,并在进程完成时报告,并为大多数进程添加了非零退出状态。该代码还在分叉之前刷新标准输出以保持干净(即使输出将进入管道或文件)。
在我的 Mac OS X 10.11.1 El Capitan 机器上,例如:
main pid is:46730
main pid 46730 forked child 46731
main pid 46730 forked child 46732
child pid 46731 forked child 46733
Child1: PID = 46731, PPID = 46730
child pid 46732 forked child 46734
main pid 46731 forked child 46735
Child1: PID = 46732, PPID = 46730
Child2: PID = 46733, PPID = 46731
Child2: PID = 46734, PPID = 46732
PID 46734: finished
main pid 46733 forked child 46736
PID 46732: child 46734 died with status 8E00
PID 46732: finished
child pid 46735 forked child 46737
Child1: PID = 46735, PPID = 46731
PID 46730: child 46732 died with status 8C00
Child2: PID = 46737, PPID = 46735
child pid 46736 forked child 46738
Child1: PID = 46736, PPID = 46733
PID 46737: finished
Child2: PID = 46738, PPID = 46736
PID 46735: child 46737 died with status 9100
PID 46735: finished
PID 46738: finished
PID 46736: child 46738 died with status 9200
PID 46731: child 46735 died with status 8F00
PID 46736: finished
PID 46733: child 46736 died with status 9000
PID 46733: finished
PID 46731: child 46733 died with status 8D00
PID 46731: finished
PID 46730: child 46731 died with status 8B00
PID 46730: finished
当您研究该输出中的顺序时,会发现一些有趣的执行交错。
None 这解释了为什么你得到 1118;在许多方面,这是无法解释的,因为没有人可以完全按照您机器上的顺序排序。但是,我所展示的是似是而非的行为,它不会重现 'all processes have a single PID as the PPID'。您应该能够对代码进行增量监控改进,并演示哪些更改会改变您机器上的行为。
我在做一个多进程的实践。我只是想查看一下父进程id,和我想象的不太一样。这是我的代码:
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/ipc.h>
#include <string.h>
#include <sys/sem.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
void child1()
{
//printf("we are child1..\n");
printf("my pid is:%d\n",getpid());
printf("I am child1..\n");
}
void child2()
{
//printf("we are child2..\n");
printf("my pid is:%d\n",getpid());
printf("I am child2.., my parent is:%d\n",getppid());
}
int main()
{
pid_t childpid[4];
int i;
printf("main pid is:%d\n",getpid());
for (i=0;i<2;i++)
{
childpid[i] = fork();
if (childpid[i]<0)
printf("fork fail..\n");
else if (childpid[i]==0)
{
childpid[i+2] = fork();
if (childpid[i+2] <0)
printf("fork inside fail..\n");
else if (childpid[i+2]==0)
child2();
else // this is parent process..
child1();
}
}
}
执行结果如下:
my pid is:3951
I am child1..
my pid is:3950
I am child1..
my pid is:3952
I am child2.., my parent is:1118
my pid is:3954
I am child1..
my pid is:3953
I am child2.., my parent is:1118
my pid is:3956
I am child1..
my pid is:3955
I am child2.., my parent is:1118
my pid is:3957
I am child2.., my parent is:1118
因为我的 child2 进程是在 process1 内部分叉的,我预计父 pid 可能是 like:3950。我的结果怎么来的 get:1118?
感谢您的帮助!
您的进程不会等待其子进程终止。最有可能的是,父进程已经终止并且子进程被重新设置。
当我 运行 逐字记录您的代码时(嗯,好的;我将 void
添加到每个空参数列表并使子函数成为 static
),然后我得到示例输出:
main pid is:46761
my pid is:46762
I am child1..
my pid is:46763
my pid is:46764
I am child1..
I am child2.., my parent is:46762
my pid is:46765
I am child2.., my parent is:1
my pid is:46766
I am child1..
my pid is:46768
my pid is:46767
I am child2.., my parent is:46766
I am child1..
my pid is:46769
I am child2.., my parent is:1
为了娱乐价值,我运行输出到一个管道得到:
main pid is:46770
main pid is:46770
my pid is:46773
I am child1..
main pid is:46770
my pid is:46772
I am child1..
main pid is:46770
my pid is:46775
I am child2.., my parent is:1
main pid is:46770
my pid is:46774
I am child2.., my parent is:46772
main pid is:46770
my pid is:46772
I am child1..
my pid is:46776
I am child1..
main pid is:46770
my pid is:46772
I am child1..
my pid is:46778
I am child2.., my parent is:1
main pid is:46770
my pid is:46774
I am child2.., my parent is:46772
my pid is:46777
I am child1..
main pid is:46770
my pid is:46774
I am child2.., my parent is:46772
my pid is:46779
I am child2.., my parent is:46777
有关该行为的解释,请参阅 printf()
anomaly after fork()
。
然后我对你的代码进行了稍微不同的检测,但核心逻辑没有改变:
#include <stdio.h>
#include <sys/wait.h>
#include <unistd.h>
static void child1(void)
{
printf("Child1: PID = %d, PPID = %d\n", (int)getpid(), (int)getppid());
}
static void child2(void)
{
printf("Child2: PID = %d, PPID = %d\n", (int)getpid(), (int)getppid());
}
int main(void)
{
pid_t childpid[4];
int i;
printf("main pid is:%d\n", getpid());
for (i = 0; i < 2; i++)
{
fflush(0);
childpid[i] = fork();
if (childpid[i] < 0)
printf("fork fail in PID %d\n", getpid());
else if (childpid[i] == 0)
{
childpid[i + 2] = fork();
if (childpid[i + 2] < 0)
printf("fork fail in PID %d\n", getpid());
else if (childpid[i + 2] == 0)
child2();
else
{
printf("child pid %d forked child %d\n", (int)getpid(), (int)childpid[i+2]);
child1();
}
}
else
printf("main pid %d forked child %d\n", (int)getpid(), (int)childpid[i]);
}
int status;
int corpse;
while ((corpse = wait(&status)) != -1)
printf("PID %d: child %d died with status %.4X\n", (int)getpid(), corpse, status);
printf("PID %d: finished\n", (int)getpid());
return getpid() % 256;
}
我确实添加了等待子进程死亡的代码,并在进程完成时报告,并为大多数进程添加了非零退出状态。该代码还在分叉之前刷新标准输出以保持干净(即使输出将进入管道或文件)。
在我的 Mac OS X 10.11.1 El Capitan 机器上,例如:
main pid is:46730
main pid 46730 forked child 46731
main pid 46730 forked child 46732
child pid 46731 forked child 46733
Child1: PID = 46731, PPID = 46730
child pid 46732 forked child 46734
main pid 46731 forked child 46735
Child1: PID = 46732, PPID = 46730
Child2: PID = 46733, PPID = 46731
Child2: PID = 46734, PPID = 46732
PID 46734: finished
main pid 46733 forked child 46736
PID 46732: child 46734 died with status 8E00
PID 46732: finished
child pid 46735 forked child 46737
Child1: PID = 46735, PPID = 46731
PID 46730: child 46732 died with status 8C00
Child2: PID = 46737, PPID = 46735
child pid 46736 forked child 46738
Child1: PID = 46736, PPID = 46733
PID 46737: finished
Child2: PID = 46738, PPID = 46736
PID 46735: child 46737 died with status 9100
PID 46735: finished
PID 46738: finished
PID 46736: child 46738 died with status 9200
PID 46731: child 46735 died with status 8F00
PID 46736: finished
PID 46733: child 46736 died with status 9000
PID 46733: finished
PID 46731: child 46733 died with status 8D00
PID 46731: finished
PID 46730: child 46731 died with status 8B00
PID 46730: finished
当您研究该输出中的顺序时,会发现一些有趣的执行交错。
None 这解释了为什么你得到 1118;在许多方面,这是无法解释的,因为没有人可以完全按照您机器上的顺序排序。但是,我所展示的是似是而非的行为,它不会重现 'all processes have a single PID as the PPID'。您应该能够对代码进行增量监控改进,并演示哪些更改会改变您机器上的行为。