我这里有两个代码示例
#include<stdio.h>
int main()
{
int i = 0;
i++;
fork();
printf("i - %d, pid - %d, addr -%p\n",i,getpid(),&i);
return 0;
}
user@Ubuntu ~/Arena/c $ ./a
i - 1, pid - 6765, addr -0x7fffd892950c
i - 1, pid - 6766, addr -0x7fffd892950c
我的第二个程序是
#include<stdio.h>
int main()
{
int i = 0;
i++;
printf("i - %d, pid - %d, addr -%p\n",i,getpid(),&i);
fork();
return 0;
}
user@Ubuntu ~/Arena/c $ ./b
i - 1, pid - 6772, addr -0x7fff39120f2c
据我所知,fork应该从上到下创建一个完整的父程序副本并执行它,如果是这样的话,为什么fork()
调用的位置做出如此大的差异?有人可以解释为什么我的第二个程序中省略了printf
吗?
答案 0 :(得分:4)
fork()创建进程的副本,并在调用fork()时继续执行这两个进程。
所以在你的第二个例子中,当只有一个进程时,你的printf会在fork之前执行。
答案 1 :(得分:2)
Fork创建程序的完整副本,但从调用fork
的位置继续执行。将printf
放在fork之后,看看会发生什么。
通常fork
来电后会检查fork
是否返回了孩子的pid
。如果确实如此,那么您当前正在运行的进程是接收子进程pid的父进程,以便能够管理子进程,如果没有,那么您当前正在运行的进程是子进程。
答案 2 :(得分:0)
为了进一步启发,请尝试:
#include <stdio.h>
#include <unistd.h>
int main(void)
{
int i = 0;
i++;
printf("A: i - %d, pid - %d, addr -%p", i, getpid(), &i);
fork();
printf("\nB: i - %d, pid - %d, addr -%p\n", i, getpid(), &i);
return 0;
}
第一个printf()
不包含换行符,因此输出保存在内存中。第二个printf()
包含换行符,因此输出在程序分叉后出现。您应该在标记为A
的两行中看到相同的信息;您应该在标记为B
的两行中看到不同的信息。
在单线程应用程序中,除了PID,父PID和fork()
返回的值之外,父进程和子进程几乎完全相同。有关完整的详细信息,请参阅fork()
的POSIX规范。