进程创建&父子进程资源分配

目录:
1.父子执行顺序问题。
2.子进程资源申请问题。
3.示例:父子进程是共享还是额外创建PCB空间
4.示例:创建子进程时,文件流中的缓冲区会拷贝一份

5.示例:创建子进程时,文件流缓冲区拷贝示例2


1.父子执行顺序问题。
父子进程在创建完子进程后互相不关联,以独立身份抢占 CPU 资源,具体谁先执行由调度算法决定,用户空间没有办法干预。子进程执行代码的位置是 fork/vfork 函数返回的位置。


2.子进程资源申请问题。
子进程重新申请新的物理内存空间,复制父亲进程地址空间所有的信息(当然,现在的操作系统实际采用写时复制等策略,真正的物理内存空间发生在需要写入时)。
子进程复制父亲进程的代码段,数据段,BSS 段,堆,栈所有用户空间的信息,在内核中操作系统为其重新申请了一个 PCB,并且使用父亲进程的 PCB 来初始化,除了 pid等特殊信息外,几乎所有的信息都是一样的。


3.示例:父子进程是共享还是额外创建PCB空间

结论:额外创建PCB空间

#include <stdio.h>
#include <stdlib.h>
#include "apue.h"
#include <sys/wait.h>

int glob = 100;

int main(int argc,char *argv[])
{
    int temp = 20;
    pid_t pid = fork();
    if(pid == -1)
    {
        perror("fork");
    }
    else if(pid == 0)//子进程
    {
        glob = 200;
        temp = 10;
        printf("child glob:%d,temp:%d\n",glob,temp);
        printf("child &glob:%p,&temp:%p\n",&glob,&temp);

    }
    else//父进程
    {
        sleep(2);
        printf("father glob:%d,temp:%d\n",glob,temp);
        printf("father &glob:%p,&temp:%p\n",&glob,&temp);
        exit(0);
    }
    return 0;
}

执行结果:



以上代码看,在子进程中先修改变量的值,并 不影响父亲进程,说明数据段,栈(当然也包括其它用户空间内存),子进程是申请新的物理空间。

但是从打印的地址来看,好像是一样的,又是同一段内存?其实不一样,这里打印的是虚拟地址,而不是物理地址编号;两个进程的虚拟地址空间是没有任何联系的。


4.示例:创建子进程时,文件流中的缓冲区会拷贝一份

#include <stdio.h>
#include <stdlib.h>
#include "apue.h"
#include <sys/wait.h>

int glob = 100;

int main(int argc,char *argv[])
{
    int temp = 20;
    printf("hello\nworld");
    fork();
    printf("bye\n");
    sleep(5);
    return 0;
}
结果:



流的缓冲区会缓存没有刷新的信息,且缓冲区在用户空间中,虽然子进程创建后从 fork 返回处执行,但缓冲区被子进程复制了一份,这样存储在缓冲区中的“world”也被复制了一份,因此,输出了两份“world”。


5.示例:创建子进程时,文件流缓冲区拷贝示例2

#include <stdio.h>
#include <stdlib.h>
#include "apue.h"
#include <sys/wait.h>

int glob = 100;

int main(int argc,char *argv[])
{
    int i = 0;
    for(i = 0;i<2;i++)
    {
        fork();
        printf("*");
    }
    sleep(12);
    return 0;
}

运行结果:输出8个*(4个进程)


a.i=0时,fork()之后:父进程(pid=200),子进程(pid=201)

b.i=1时

pid=200的进程,fork()之后:父进程(pid=200),子进程(pid=202)

pid=201的进程,fork()之后:进程(pid=201),子进程(pid=203)


结论:4个进程200,201,202,203

由于子进程会完全拷贝一份父进程的资源,所以最终为8个*



展开阅读全文

没有更多推荐了,返回首页