zoukankan      html  css  js  c++  java
  • Linux_ fork 进程操作

    1. 什么是进程

      程序的运行实例,就是“进程”
      一个程序,同时执行多次,则产生多个不同的进程。

      程序是静态的
      进程是动态的

    2. 进程的结构
      进程的组成:程序代码、数据、变量、文件描述符(表示已打开的文件)、环境等组成。

      每个进程有一个唯一的编号,称为”进程标识符”(PID)
      PID >= 2
      PID=1的进程是init进程。

      进程之间共享程序代码
      即,同一个程序的多个进程,共享一个代码拷贝。

      进程之间共享函数库。

      进程有自己的”栈空间”、“程序计数器”、变量。

    3. 进程表
      Linux把所有进程的相关信息放在一个表中,称为进程表
      每个进程是一个表项。
      进程表的索引,是PID

      可同时运行的进程数取决于该进程表的容量。

    4. 进程的查看
      ps 显示与该终端连接的进程。
      ps -ef
      ps ax

    5. 进程的状态
      ps ax
      ps的stat列表示进程的状态:
      S: 睡眠,即“挂起”,等待某个事件的发生。
      R: 运行
      D: 不可中断的睡眠
      T: 停止
      Z: 死进程(僵尸进程)
      s: 进程是会话期的首进程。
      +:进程属于前台进程

    6. 进程的调度
      单处理器上,同一个时刻只能有一个进程运行。
      Linux内核用“进程调度器”来决定下一个时间片执行哪个进程。

    7. 进程的启动
      1)system
      实例:main7.c

      在程序的内部,创建一个新进程,执行指定的shell命令。
      
      主进程将等待新进程执行结束后,才能继续执行。
      除非新进程以后台方式运行,system("ls &") 
      
      效率不高,因为要先启动shell, 然后再运行指定的shell命令。
      

      2) exec (进程替换)
      exec指一组函数.
      用于:从当前进程切换到另一个程序执行,且不返回到原来的程序(除非发生了错误,返回-1)。

      "l"组 (l即list, 新程序的参数为列表形式,即可变参数列表)
      execl
      execlp
      execle
      
      “v"组(v即vector, 新程序的参数为数组形式, 参数个数不变
      execv
      execvp
      execve
      
      p后缀:
      第一个参数是要执行的文件名,不含路径。
      文件的路径由系统默认的环境变量(path)指定。
      
      e后缀:
      最后一个参数是字符串数组,表示指定的环境变量。
      注意,这个环境变量是指程序替换以后,
            新程序运行期间的环境变量。
        而不是替换新程序时的环境变量,
        所以execle函数的第一个参数仍然需要使用路径。
        替换到新程序以后,此时的环境就是execle的最后一个参数。
      
      实例:main8.c
      分别用以上六种形式,创建"ls -l"进程。
      
      注意:
      exec启动的新进程继承原进程的很多特性:
      比如,原进程中打开的文件描述符,在新进程中仍保持打开。
      

      3) fork (进程复制)
      复制的新进程(子进程),与原进程一模一样,
      但有自己的数据空间、环境、文件描述符等。

       fork的返回值
       在原进程(父进程)中,fork返回新进程(子进程)的PID
       在新进程(子进程)中,fork返回0
       fork失败,返回-1
             失败原因:父进程能拥有的子进程数超出限制(CHILD_MAX)
                            进程表中的空间不足
                            虚拟内存不足
      

      实例:main9.c

    8. 等待子进程结束
      1) wait
      功能:父进程等待任意它的任一个子进程结束
      返回该结束子进程的PID
      参数: 实参非空时,返回子进程的退出状态。
      参见man 2 wait

      实例:main10.c

      2) waitpid
      功能:父进程等待指定的子进程。
      参数:
      详见man 2 waitpid
      参数3常使用WNOHANG(不阻塞,立即返回)
      实例:
      waitpid(child_pid, (int*)0, WNOHANG);
      如果子进程未结束、未终止,则返回0
      已经子进程已结束, 则返回子进程的PID
      如果失败, 返回-1

      1. 僵尸进程

        1) 什么是僵尸进程
        僵死进程(死进程):是指该进程已经结束运行,但在进程表中还没有删除它的相关信息。

        2)僵死进程产生的原因
        子进程比父进程先结束,(儿子比父亲先“死”)
        但是又不能在进程表中删除子进程的表项,因为父进程调用wait时还需要这些信息。

        3)僵尸进程的“归宿”
        子进程比父进程先结束后,成为僵尸进程。
        直到父进程也结束,该僵尸进程才真正消亡(从进程表中删除其表项)

        如果父进程被异常终止,则该僵尸进程认init进程为“父进程”
        init进程发现该僵尸子进程后,再把它清除。

        应该尽量避免产生僵尸进程。
        僵尸进程虽不再运行,但仍占用系统的资源!

        main11.c
        测试:gcc main11.c
        ./a.out &
        ps /* 子进程结束后 */

    你知道:

     for (i=0; i<2; i++) {
                fork();
           }
       一共创建了多少个进程?
    
  • 相关阅读:
    自制的 MPlayer Skin
    mplayer filter 参数及效果
    可拖动的层DIV的完整源代码【转】
    Hibernate的检索方式(一)【转】
    HQL经典语句
    常适用的特效网页代码
    C#优化字符串操作【转】
    Hibernate的检索方式(二)【转】
    内联inline的使用方法【转】
    Hibernate的检索方式(三)【转】
  • 原文地址:https://www.cnblogs.com/Sico2Sico/p/5384223.html
Copyright © 2011-2022 走看看