美文网首页
3.6、fork函数详解、范例演示

3.6、fork函数详解、范例演示

作者: 奥斯特洛司机 | 来源:发表于2019-04-01 16:11 被阅读0次

    1、fork()函数简单认识
    用来创建进程,
    进程的概念:一个可执行程序执行起来就是一个进程。
    多个进程可以共享同一个可执行文件。
    在一个可执行程序中,可以用fork来创建一个子进程,他从fork指令的下一条开始执行与父进程相同的代码。内存也一样。原来一条执行通路,现在变成了两条。
    1.1、fork()函数简单范例,上图。
    ps -eo pid,ppid,sid,tty,pgrp,comm,stat | grep -E 'bash|nginx|PID'
    -E表示可以多个选项,如果是-e要写多次。
    kill -usr1 1090

      1.2、僵尸进程的产生、解决、SIGCHLD
               sudo strace -e trace=signal -p 1090 附着进程 
               kill孩子进程,父进程收到SIGCHLD信号。子进程编程僵尸进程Z+状态。
               僵尸进程的产生:一个子进程结束了,但是他的父进程还活着,
               但是该父进程没有调用wait()/waitpid()函数来进行额外的处置,
               那么子进程就会编程僵尸进程。占用pid号,整个系统pid号总共三万多个。
               内核认为父进程还需要子进程的一些收尾信息。    
               开发者不能允许僵尸进程的存在。
               解决:把父进程干掉,实际工作中不会这么干。
                          或者父进程收到SIGCHLD信号,
                          所以对于源码中有fork这种调用的行为,
                          就应该拦截并处理SIGCHLD信号。
                          waitpid(获得子进程状态)回收子进程资源。
                          上图:
    

    2、fork()函数进一步认识
    fork产生新进程的速度非常快,fork()产生的新进程并不复制原进程的内存空间,
    而是和原进程共享一个内存空间,但这个内存空间的特性是“写时复制”
    也就是说,原来的进程和fork()出来的子进程可以同时、自由的读取内存,
    但是如果子进程或者父进程对内存进行修改的话,
    那么这个内存就会复制一份给该进程单独使用,
    以免影响到共享这个内存空间的其它进程使用。
    上图:

    3、完善一下fork()代码
    fork会返回两次,父进程返回一次,子进程返回一次。
    而且fork在父进程和子进程返回的值是不同的。
    父进程返回子进程的pid,子进程返回0 ;
    也为全局量发生改变,此时父子进程单独一块内存。
    3.1、一个和fork()执行有关的逻辑判断
    上图:((fork() && fork()) || (fork() && fork())) 7个进程。
    或:有1出1,全0出0
    与:全1出1,有0出0
    分析:第一个fork分成两条,等于0 的不用执行第二个fork,
    但需要执行第三个fork,等于0的不用执行第4个fork,
    大于0的分支的要执行第4个fork,
    所以第一个fork=0的总共分出3条进程。
    一次类推,第一个fork=1的分出4条进程。

    4、fork()失败的可能性
    1、系统中进程太多,可能是僵尸进程太多。
    缺省情况下,最大的pid是32767,16位。
    2、每个用户有个可以开启的最大的的进程数。
    printf("%ld" , sysconf(_SC_CHILD_MAX)); 一般7788左右。

    相关文章

      网友评论

          本文标题:3.6、fork函数详解、范例演示

          本文链接:https://www.haomeiwen.com/subject/rsvvbqtx.html