什么时候调用fork()?

时间:2013-11-05 15:25:52

标签: c fork

我这里有两个代码示例

#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吗?

3 个答案:

答案 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规范。