简体   繁体   English

这个C代码做了什么?

[英]What does this C code do?

I'm really new to C programming, although I have done quite a bit of other types of programming. 我是C编程的新手,虽然我做了很多其他类型的编程。

I was wondering if someone could explain to me why this program outputs 10. 我想知道是否有人可以向我解释为什么这个程序输出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);
    }
}

I know the output is "parent: value = 10". 我知道输出是“parent:value = 10”。 Anyone know why? 谁知道为什么?

Thanks! 谢谢!

fork creates two processes (the "parent" and the "child"). fork创建两个进程(“父”和“子”)。 Each process has a different value of pid in your example. 在您的示例中,每个进程都有不同的pid值。 The child process has a pid of 0. The parent process has a pid of the child's operating system pid (assigned by the OS.) 子进程的pid为0.父进程有一个子操作系统pid的pid(由操作系统分配)。

In your example, each process has it's own value in its memory. 在您的示例中,每个进程在其内存中都有自己的value They do not share memory (like you think they should by your question.) If you change one process (the first part of the if) it will not be reflected in the second process (the second part of the if.) 它们共享内存(就像你认为它们应该通过你的问题。)如果你改变一个进程(if的第一部分),它将不会反映在第二个进程中(if的第二部分)。

Edit: Explained the value of pid. 编辑:解释pid的值。

About fork() : 关于fork():

  • If fork() returns a negative value, the creation of a child process was unsuccessful. 如果fork()返回负值,则子进程的创建不成功。
  • If fork() returns a zero to the newly created child process. 如果fork()向新创建的子进程返回零。
  • If fork() returns a positive value, the process ID of the child process, to the parent. 如果fork()返回一个正值,则将子进程的进程ID返回给父进程。

So in you case it bound to return a number greater than 0 & thus the value will remain 10 & will be printed. 所以在你的情况下,它必然会返回一个大于0的数字,因此该值将保持为10并将被打印。

Well, fork spawns a new process. 好吧, fork产生一个新进程。 It more or less copies the current process, and both the new one (the child) and the old one (the parent) go on at the same point in the code. 它或多或少地复制当前进程,新的(子)和旧的(父)在代码中的同一点继续。 But there is one significant difference (that interests us) here: for the child, fork returns 0. For the parent, it returns the process ID of the child. 但是这里有一个显着的区别(我们感兴趣):对于子级, fork返回0.对于父级,它返回子级的进程ID。

So the if(pid ==0) part is true for the child. 所以if(pid ==0)部分对于孩子来说是真的。 The child simple add 10 to his value , and then exits since there is no further code. 孩子简单地将10添加到他的 value ,然后退出,因为没有其他代码。

The else part is true for the parent (except for the very rare case that fork returned an error with -1). else部分对于父级是正确的(除了非常罕见的情况, fork返回错误为-1)。 The parent simply wait s for the child to exit. 父母只是wait孩子退出。 But the child has modified its own copy of value , the one of the parent is still untouched and that is why you get the output of "10". 但是孩子已经修改了自己的value副本,父母之一仍未触及,这就是为什么你得到“10”的输出。 Then the parent also exits. 然后父母也退出。

fork() creates a new process: it has two return values in two different contexts, so both paths run in your if statement. fork()创建一个新进程:它在两个不同的上下文中有两个返回值,因此两个路径都在if语句中运行。 The conditional is mostly used to determine which process you run in after the fork. 条件主要用于确定在fork之后运行的进程。

when you call fork , it creates a copy of the process in such a way that both the copies' program counter s are at the same position in their code sections. 当你调用fork ,它会创建一个进程的副本,使得两个副本的program counter在它们的代码段中处于相同的位置。 Hence when any of these copies resumes execution, both will just be finishing the call to fork . 因此,当任何这些副本恢复执行时,两者都将完成对fork的调用。

So both of them should execute identically. 所以它们都应该执行相同的。

BUT, fork returns 0 in the child process, and the pid of the child process in the parent process. 但是, fork在子进程中返回0 ,子进程的pid在父进程中返回。

That explains the mojo behind the if( pid==0 ) part. 这解释了if( pid==0 )部分背后的mojo。

So when the child process changes the value of value , it actually changes that in its own copy (remember: the process got copied, so the data sections got copied too). 因此,当子进程更改value的value ,它实际上会更改它自己的副本(请记住:进程已被复制,因此数据部分也被复制)。

Meanwhile, the parent process executes with its old value of value , which is 10. 同时,父进程执行与它的旧的值value ,即10。

Even after the child changes its copy of value and dies, the parent's copy is still 10. 即使在孩子改变其value副本并且死亡之后,父母的副本仍然是10。

The fork system call creates a new process as a child of the existing (parent) process. fork系统调用创建一个新进程作为现有(父)进程的子进程。 Both the parent and the child continue execution at the line following the fork statement, however the child process is given an exact copy of the parents address space. 父级和子级都在fork语句后面的行继续执行,但子进程被给予父级地址空间的精确副本。

The fork system call returns the process id of the newly created process to the parent and zero to the child, therefore within this code the child will increment its own copy of the value variable and the parent will print out its own copy. fork系统调用将新创建的进程的进程id返回给父进程,并将零返回给子进程,因此在此代码中,子进程将递增自己的value变量副本,并且父进程将打印出自己的副本。

You will often see fork followed by an exec within the child so that it replaces itself with another program. 您经常会在子项中看到fork后跟一个exec,以便它替换为另一个程序。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM