2010-09-16 143 views
4

虽然我已经完成了很多其他类型的编程,但我对C编程确实很陌生。这个C代码是做什么的?

我想知道如果有人能向我解释为什么这个计划产出10

#include <stdio.h> 
#include <sys/types.h> 
#include <unistd.h> 
#include <sys/wait.h> 
#include <stdlib.h> 

int value = 10; 

int main() 
{ 
    pid_t pid; 

    pid = fork(); 
    if(pid == 0){ 
    value += 10; 
    } 
    else if(pid > 0){ 
     wait(NULL); 
     printf("parent: value = %d\n", value); //Line A 
     exit(0); 
    } 
} 

我知道输出是“父:值= 10”。有人知道为什么

谢谢!

+0

谢谢你!完全理解现在正在发生什么! – kralco626 2010-09-16 20:31:18

+0

这是一些编程课程中常见的功课题,它的功课不是吗? – ldog 2010-09-16 20:34:20

+0

如果您对答案满意,那么标记最佳答案是个好习惯。这将奖励海报,并让其他人知道问题已经解决。 – 2010-09-16 20:49:50

回答

4

关于叉():

  • 如果fork()的返回负值, 创建一个子进程是 不成功。
  • 如果fork()将0返回给新创建的子进程 。
  • 如果fork()返回一个正值,则子进程的进程ID为 ,为父进程的 。

所以在你区分它绑定到返回一个大于0的数&因此值将保持10 &将被打印。

+0

真棒回答。我正在试图围绕这个包裹我的头。所以父进程得到一个大于0的数字,因此进入else部分并打印。子进程得到0.这个子进程是做什么的?它是否创建了一个从当前行执行的新过程?或从代码的开始? – kralco626 2010-09-16 20:24:46

+0

@ kralco626它是父进程的副本,从相同的点/状态执行:http://man.cx/fork%282%29 – Bruno 2010-09-16 20:30:18

16

fork创建两个进程(“父”和“子”)。在你的例子中,每个进程都有不同的pid值。子进程的pid为0.父进程具有子进程的操作系统pid的pid(由操作系统分配)。

在您的示例中,每个进程在其内存中都有自己的value。他们做不是共享内存(就像你认为他们应该由你的问题所示)。如果你改变一个进程(if的第一部分),它不会反映在第二个进程中(if的第二部分)。

编辑:解释了pid的值。

+3

由fork返回的pid对于子进程是0,对于父进程是大于0。 – 2010-09-16 20:19:37

+0

为什么儿童进程PID为0?为什么父进程不是0,每个孩子都从那里增加? – kralco626 2010-09-16 20:22:03

+0

@ kralco626:'man fork'说:“成功时,子进程的PID返回父进程,并且0返回给子进程。” – Bruno 2010-09-16 20:24:44

0

fork()创建一个新的进程:它在两个不同的上下文中有两个返回值,所以两个路径都在你的if语句中运行。条件主要用于确定在fork后运行哪个进程。

+0

但只有一条输出线。你能带我看看发生了什么事吗?为什么父级和子级进程不创建和输出语句? – kralco626 2010-09-16 20:20:49

+0

因为在孩子中,fork返回0.在父代中,fork返回孩子的pid。 – 2010-09-16 20:22:20

+0

哈哈你现在我明白了。进程从fork()调用点分离。子进程的值为0,父进程的值大于0.我想我明白了! – kralco626 2010-09-16 20:28:19

2

那么,fork催生了一个新的过程。它或多或少会复制当前进程,并且新代码(子代)和旧代码(父代)在代码中的同一点继续进行。但是这里有一个显着的区别(我们感兴趣):对于孩子,fork返回0.对于父亲,它返回孩子的进程ID。

所以if(pid ==0)部分是真实的孩子。孩子简单地添加10到他的value,然后退出,因为没有进一步的代码。

else部分对于父级是正确的(除非极少数情况下fork返回-1错误)。父母简单地wait s为孩子退出。但是孩子已经修改了自己的副本value,父母的一个仍然没有被触动,这就是为什么你得到“10”的输出。然后父母也退出。

0

当您拨打fork时,它会创建一个过程副本,使副本'program counter s在其代码部分处于相同位置。因此,当这些副本中的任何一个恢复执行时,两者都将完成对fork的呼叫。

所以他们都应该执行相同的。

但是,fork在子进程中返回0,并在父进程中返回子进程的pid

这解释了if(pid==0)部分背后的魔咒。

所以当子进程更改value的值时,它实际上改变了它自己的副本(记住:进程已被复制,因此数据部分也被复制了)。

同时,父进程及其古老的value价值,这是10

孩子改变其副本value即使在和死亡,父母的副本仍然是10

0

叉执行系统调用将创建一个新的进程作为现有(父)进程的子进程。父对象和子对象都继续在fork语句后面的行中执行,但子进程被赋予父对象地址空间的精确副本。

fork系统调用会将新创建的进程的进程ID返回给父进程,并将其返回给子进程,因此在此代码中,子进程会增加自己的值变量副本,并且父进程会打印出自己的副本。

你会经常看到fork后面跟着一个exec在子内部,这样它就可以用另一个程序代替它自己了。