打印

一个main函数引起两个进程执行的原因

[复制链接]
142|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
卡拉瓦乔|  楼主 | 2018-9-27 16:36 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
在一个main函数中调用fork函数一次会引起两个进程交替执行。

上午的时候这个问题绕到我了,我翻了一下手中的《linux程序设计》,讲的含糊不清的;我又看了一下《unix环境高级编程》,讲的是很多,但是看了以后一头雾水,还好在这里我找到了很好的解释,









大致是这样的:

首先看一个我们经常看到的fork()系统调用的小例子:

#include <sys/types.h>

#include <sys/wait.h>

#include <unistd.h>

#include <stdio.h>

#include <stdlib.h>

int main()

{

        pid_t pid;

        char *message;

        int n;

        int exit_code;



        printf("fork program starting\n");

        pid = fork();

        switch(pid)

        {

        case -1:

        perror("fork failed");

        exit(1);

        case 0:

        message = "this is the child";

        n = 5;

        exit_code = 37;

        break;

        default:

        message = "this is parent";

        n = 3;

        exit_code = 0;

        break;

        }

        for( ; n > 0; n --)

        {

        puts(message);

        sleep(1);

        }

        exit(0);

}

        执行结果如下:

xiahuixia@xiahuixia-Inspiron-3437:~/study/code$ ./process

fork program starting

this is parent

this is the child

this is parent

this is the child

this is parent

this is the child

this is the child



再看一下fork()函数的说明,至少也比中文版的印刷物讲的好一些:

System call fork() is used to create processes.  It takes no argumentsand returns a process ID.  The purpose of fork() is to create a new process, which becomes the child process of thecaller.  After a new child process is created, both processes will execute the next instruction following the fork() system call.  Therefore, we have to distinguish the parent from the child.  This can be done by testing the returned value of fork():



很好懂,不是吗?但是它还没有指明为什么会有两个进程同时交替执行。

再看:

If fork() returns a negative value, the creation of a child          process was unsuccessful.           fork() returns a zero to the newly created child process.           fork() returns a positive value, the           process ID of the child process, to the parent.            The returned process ID is of type pid_t defined in           sys/types.h

.  Normally,          the process ID is an integer.  Moreover, a process can use          function getpid() to retrieve the process ID assigned to          this process.   上面这些似乎还是不太好懂,

再看:

Therefore, after the system call to fork(), a simple test can tell which process is the child.  Please note that Unix will make an exact copy of the parent's address space and give it to the child.   Therefore, the parent and child processes have separate address spaces.

看到红字的这段了吗?它说明了原因。

再用图解释一下,你就明白了:

Suppose the above program executes up to the point ofthe call to fork() (marked in red color):









If the call to fork() is executed successfully, Unix will

make two identical copies of address spaces, one for the parent          and the other for the child.           Both processes will start their execution at the next           statement following the fork() call.  In this case,          both processes will start their execution at the assignment          statement as shown below:         









Both processes start their execution right after the system call fork().  Since both processes have identical but separate address spaces, those variables initialized beforethe fork() call have the same values in both address spaces.Since every process has its own address space, any modifications will be independent of the others.  In other words, if the parent changes the value of its variable, the modification will only affect the variable in the parentprocess's address space.  Other address spaces created by fork()calls will not be affected even though they have identical variable names



关键一点是:并不是一个main 函数中有两个进程在运行,而是子进程复制了父进程的代码空间,也就是说父进程的main函数也被复制了过来,只不过执行点是从fork()的下一条指令开始;而此时父进程也在执行,执行点也是fork的下一条指令。所以给人一种假象,似乎是



int main()

{

        pid_t pid;

        char *message;

        int n;

        int exit_code;



        printf("fork program starting\n");

        pid = fork();

        switch(pid)

        {

        case -1:

        perror("fork failed");

        exit(1);

        case 0:

        message = "this is the child";

        n = 5;

        exit_code = 37;

        break;

        default:

        message = "this is parent";

        n = 3;

        exit_code = 0;

        break;

        }

        for( ; n > 0; n --)

        {

        puts(message);

        sleep(1);

        }

        exit(0);

}这段main函数中有两个进程在执行。

使用特权

评论回复

相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

438

主题

438

帖子

0

粉丝