首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >理解C中的fork()顺序

理解C中的fork()顺序
EN

Stack Overflow用户
提问于 2018-12-11 06:50:41
回答 2查看 261关注 0票数 1

所以我有一个我想要理解的程序,它来自一个旧的考试,但我就是不能掌握它。我如何知道fork的顺序以及变量是如何改变的?

代码语言:javascript
复制
static int g = -1;

int main(int argc, char *argv[])
{
    int v = 0;
    pid_t p;

    while (v++ < 6)
        if ((p = fork()) < 0) {
            perror("fork error");
            return 1;
        } else if (p == 0) {
            v++;
            g--;
        } else {
            g++;
            v+=3;
        if (waitpid(p, NULL, 0) != p) {
            perror("waitpid error");
            return 1;
        }
    }
    printf("mypid = %d parentpid = %d p = %d v = %d g = %d\n",
    getpid(), getppid(), p, v, g);
    return 0;
}
EN

回答 2

Stack Overflow用户

发布于 2018-12-11 07:09:52

fork()的调用既会启动一个新进程,又会继续执行旧进程。如果有某种错误,它会返回一个error值。所有错误和只有错误都是负数。这是第一个if块检查的内容。

在新进程中,fork()返回0。因此,递增v和递减g的分支仅在子进程中调用,而不是在父进程中调用。

在原始进程中,fork()函数返回子进程的进程标识符(PID),它是一个正整数。(这将在稍后传递给waitpid()。因此,只在父进程中调用递减v和递增g的分支,而不是子进程。

每个进程都有自己的vg副本。(这是进程和线程之间的主要区别:线程共享内存。)在现代的SMP操作系统上,子进程将获得父进程的内存映射的副本。但它们指的是相同的物理内存页面,直到一个进程或另一个进程写入它们。当发生这种情况时,将对该页内存进行复制,两个进程现在都会获得自己的、不同的副本。

按照现代Linux内核实现fork()的方式,子进程将在父进程之前继续。这对性能有很大的影响。大多数调用fork()的程序都会立即让子进程调用exec()来启动新程序。这意味着它根本不需要父内存的副本。(现在有一种更新、更简单的方法可以在新进程中启动不同的程序,即posix_spawn()。)另一方面,父进程几乎总是保持运行并修改其内存。因此,让子进程有机会声明它将丢弃继承的内存,这意味着父进程不需要担心为其子进程留下任何内存页面的未经修改的副本,内核也不必经历写时复制的繁琐过程。

但在实践中,任何像样的编译器都会将这两个局部变量都保存在寄存器中,因此不会出现这个问题。

在循环的下一次迭代中(仅在子进程终止后发生),将使用父进程变量的更新值生成一个新子进程。每个子进程还使用从其父进程继承的相同的vg值继续运行循环。

票数 2
EN

Stack Overflow用户

发布于 2018-12-11 07:19:56

每个对fork的调用都会使用自己的变量生成自己的进程,这些变量会在调用时被复制(逻辑上,当实际复制发生时,优化可能会发生变化,但不会改变结果)。

所以当你进入循环时,v递增到1,然后你分叉。此时,父进程具有g=-1,v=1,p=,而新子进程具有g=-1,v=1,p=0。然后,父进程进入else情况,将g增加到0,v增加到4,然后等待子进程完成,而子进程进入"else if (p == 0)",将v增加到2,将g减少到-2,然后再次循环。

至此,您希望已经获得了足够的信息来遵循下两个子进程的逻辑,完成循环,并打印各自的结果。当它们这样做时,第一个子进程也将使用v=6结束其等待进程,退出循环,并打印其结果。

此时,父对象将解除阻塞,再次循环(在此过程中再派生一个子对象),然后(该子对象完成后)退出循环。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53714886

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档