zoukankan      html  css  js  c++  java
  • fork函数

      复制进程映像:使用fork函数得到的子进程从父进程继承了整个进程的地址空间,包括:进程上下文、进程堆栈、内存信息、打开的文件描述符、信号控制设置、进程
    优先级、进程组号当前工作目录、根目录、资源限制、控制终端等。
      

      子进程与父进程的区别在于:
    1、父进程设置的锁,子进程不继承(例如对于一个排他锁,父进程设置了锁,子进程再设置,显然不合适)
    2、各自进程ID和父进程ID不同
    3、子进程的未决警告被清除
    4、子进程的未决信号集设置为空集
     #include <unistd.h>

    #include <sys/types.h>

     pid_t   fork(void);//无参数,失败返回-1。两次返回是在各自的地址空间中返回的
    A 进程fork进入内核 

    孤儿进程:父进程先于子进程退出,托孤给init进程
    僵尸进程:子进程先退出,父进程还未查询子进程的退出状态,子进程就处于僵死状态(defunct)。

    为何父进程返回值大于0(新进程ID号码),子进程返回0:因为子进程PCB中保存有进程ID和父进程ID,所有即便返回0,子进程也能获取这两个值;但父进程若返回0,则它

    无法得知新创建的子进程的ID。

    fork一次调用两次返回(是在各自的进程地址空间中返回的),fork成功,意味着创建了一个进程副本,两个进程。fork陷入内核,拷贝父进程代码,所以子进程也有fork,并返回。

     1 #include<unistd.h>
     2 #include<sys/types.h>
     3 #include<stdlib.h>
     4 #include<stdio.h>
     5 #include<errno.h>
     6 #include<string.h>
     7 #include<signal.h>
     8 #define ERR_EXIT(m)
     9     do
    10     {
    11         perror(m);
    12         exit(EXIT_FAILURE);
    13     }while(0)  //宏要求一条语句
    14 
    15 int main()
    16 {
    17     signal(SIGCHLD,SIG_IGN);//避免僵死进程
    18     printf("before fork pid=%d
    ",getpid());
    19     pid_t pid;
    20     pid=fork();//进程代码段、数据段、堆栈段等一样,新进程的堆栈段和PCB也跟父进程一样,所以下一条指令地址也一样,所以不会从开头运行。所以进程分支在fork之后。
    21     if(pid==-1)
    22         ERR_EXIT("fork error");
    23     if(pid>0)
    24     {
    25         printf("this is parent pid=%d, child pid=%d
    ",getpid(),pid);
    26     }
    27         
    28     else if(pid==0)
    29     {
    30         //sleep(5);//父进程先结束
    31         printf("this is child pid=%d, parent pid=%d
    ",getpid(),getppid());
    32     }
    33         
    34     return 0;
    35 }
    36 /*
    37 子进程先结束
    38 before fork pid=48714
    39 this is parent pid=48714, child pid=48715
    40 this is child pid=48715, parent pid=48714
    41 */

       fork函数陷阱:1-->2-->4-->8  (核心:fork开始,会有两个进程执行相同代码段)

    #include<unistd.h>
    #include<sys/types.h>
    #include<stdlib.h>
    #include<stdio.h>
    #include<errno.h>
    #define ERR_EXIT(m)
        do
        {
            perror(m);
            exit(EXIT_FAILURE);
        }while(0)  //宏要求一条语句
    int main()
    {
        fork();
        fork();
        fork();
        printf("ok
    ");
        return 0;
    /*8
    ok
    ok
    ok
    ok
    ok
    ok
    ok
    ok
    */
    }

      写时复制(copy   on  write):

    如果多个进程要读取(仅仅读取)它们自己的那部分资源的副本,那么复制是不必要的(比如代码段),每个进程只要保存一个指向这个资源的指针就可以了。如果一个进程要修改自己那份资源的副本,那么就会复制那份资源。这就是写时复制。资源需要修改才要复制。其他进程仍然共享。实际上不会被修改的数据是共享的。

  • 相关阅读:
    你爱的不爱你,转身是幸福
    按字节长度截取字符串(支持截取带HTML代码样式的字符串)
    存储过程操作类
    C# 拖动控件
    文件同步类
    c# 动态改变控件大小的方法
    虚拟世界改变现实 盛大兴建永恒之塔
    c#百钱买百鸡
    序列化类
    DLL专题之MFC规则库和扩展库
  • 原文地址:https://www.cnblogs.com/wsw-seu/p/8299002.html
Copyright © 2011-2022 走看看