zoukankan      html  css  js  c++  java
  • 系统编程之进程的创建.僵尸与孤儿进程

     

    一.进程

         

           进程是正在执行的程序实例。执行程序时,内核会将程序代码载入虚拟内存,为程序变量分配空间,在内核中建立相应的数据结构,以记录与进程有关的各种信息(比如,进程ID、用户ID、组ID以及终止状态等)

              在内核看来,进程是一个个实体,内核必须在它们之间共享各种计算机资源。对于像内存这样的受限资源来说,内核一开始会为进程分配一定数量的资源,并 在进程的生命周期内,统筹该进程和整个系统对资源的需求,对这一分配进行调整。程序终止时,内核会释放所有此类资源,供其他进程重新使用。其他资源(如 CPU、网络带宽等)等属于可再生资源,但必须在所有进程间平等共享。

       我们可以通过ps -aux来打印当前的所有进程,其中状态具体表示为:S表示睡眠,R表示可运行,D表示等待,T表示停止,Z表示死进程或僵尸进程,PID表示进程号,PPID表示父进程号。接下来打印当前程序的进程号和父进程号:

        

      1 #include <stdio.h>
      2 #include <sys/types.h>
      3 #include <unistd.h>
      4 
      5 //typedef unigned int pid_t
      6 int main(void)
      7 {
      8     pid_t self_pid =  getpid();
      9     pid_t parent_pid = getppid();
     10 
     11     printf("self_pid = %d
    ", self_pid);
     12     printf("parent_pid = %d
    ", parent_pid);//bash
     13 
     14     return 0;
     15 }
    ~                                                                                    
    ~                                                                                    
    ~             

      二:创建新进程:

        创建一个新的进程可以分为三种方法:systeme(),exel()族,fork();

        1,system()

          system()函数调用“/bin/sh -c command”执行特定的命令,阻塞当前进程直到command命令执行完毕

            以下是通过system来打印当前的路径:

          

      1 #include <stdio.h>
      2 #include <sys/types.h>
      3 #include <unistd.h>
      4 #include <stdlib.h>
      5 
      6 //typedef unigned int pid_t
      7 int main(void)
      8 {
      9     printf("execute this command
    ");
     10     system("pwd");
     11     printf("Over
    ");
     12 
     13 
     14     return 0;
     15 }
    ~                                                                                    
    ~                                                                                    
    ~                                                                                    
    ~    

        运行结果:

          

      

        2.exel族(execl、execlp、execle、execv、execvp)

        execl系列函数是替换类创建进程,即在创建进程的同时,把以前的进程干掉,其具体的原型为:

      

              原型:

            int execl(const char *path, const char *arg, ...);

            int execlp(const char *file, const char *arg, ...);

            int execle(const char *path, const char *arg, ..., char * const envp[]);

            int execv(const char *path, char *const argv[]);

          以下是 execl创建进程:

          

      1 #include <stdio.h>
      2 #include <sys/types.h>
      3 #include <unistd.h>
      4 #include <stdlib.h>
      5 
      6 //typedef unigned int pid_t
      7 int main(void)
      8 {
      9     printf("execute this command
    ");
     10     execlp("ls","ls","-l", (char *)0);
     11     printf("Over
    ");
     12 
     13 
     14     return 0;
     15 }

          运行结果:

        

        可以发现,以前应该打印的over那句,没有打印,这就是因为被他的子进程干掉了。

        3.fork孤儿进程

        在fork函数之前,需要了解两个概念:第一个是孤儿进程:就是一个进程的父进程比子进程先要退出,

        以下是一个孤儿进程的实例:

        

      1 #include <stdio.h>
      2 #include <sys/types.h>
      3 #include <unistd.h>
      4 #include <stdlib.h>
      5 
      6 //fork---->孤儿进程,僵尸进程,
      7 
      8 int main(void)
      9 {
     10     pid_t pd = 0;
     11     int status = 0;
     12 
     13     pd = fork();
     14 
     15     if(0 > pd)
     16     {
     17         perror("fork");
     18         exit(EXIT_FAILURE);//--->return 
     19     }
     20 
     21     if(0 == pd)
     22     {
     23         printf("this is child process:%d
    ", getpid());
     24         printf("my parent process id:%d
    ", getppid());
     25         //sleep(5);
     26         exit(9);
     27     }
     28     //子进程程序
     29     else if(0 < pd)
     30     //pd > 0
     31     {
     32         //  wait(&status);//回收子进程资源
     33         //printf("status is %d
    ", status>>8);
     34         printf("this is parent process:%d
    ", getpid());
     35         printf("my parent process id:%d
    ", getppid());
     36         //sleep(1);
     37     }
     38     //父进程程序    
     39 
     40 
     41     return 7;
     42 }

        

        运行结果:

        

             可以看到首先打印的是父进程,在打印的是子进程,子进程的父进程号为 1,1是init进程,也是所有进程的祖先进程。

        当一个进程成了孤儿进程之后,都会有init进程来回收所有的资源,所以说,孤儿进程的资源不会存在浪费。

        4.fork僵尸进程

         当一个进程结束,而父进程却没有调用wait函数来回收进程的资源。这个进程叫做僵尸进程.

         以下是一个僵尸进程的实例,让父进程睡秒之后再退出!

          

      1 #include <stdio.h>
      2 #include <sys/types.h>
      3 #include <unistd.h>
      4 #include <stdlib.h>
      5 
      6 //fork---->孤儿进程,僵尸进程,
      7 
      8 int main(void)
      9 {
     10     pid_t pd = 0;
     11     int status = 0;
     12 
     13     pd = fork();
     14 
     15     if(0 > pd)
     16     {
     17         perror("fork");
     18         exit(EXIT_FAILURE);//--->return 
     19     }
     20 
     21     if(0 == pd)
     22     {
     23         printf("this is child process:%d
    ", getpid());
     24         printf("my parent process id:%d
    ", getppid());
     25         //sleep(5);
     26         exit(9);
     27     }
     28     //子进程程序
     29     else if(0 < pd)
     30     //pd > 0
     31     {
     32         //wait(&status);//回收子进程资源
     33         //printf("status is %d
    ", status>>8);
     34         printf("this is parent process:%d
    ", getpid());
     35         printf("my parent process id:%d
    ", getppid());
     36         sleep(5);
     37     }
     38     //父进程程序    
     39 
     40 
     41     return 7;
     42 }
    ~             

        运行结果:

        

        在父进程睡的这5S中可以看到26977的状态为僵尸态。

         为了避免这种僵尸状态的出现,造成资源的浪费,需要对子进程的进行“收尸”

        一般父进程需要调用wait函数来等待子进程退出之后再退出。

        接下来是一个正常退出的进程:

        

      1 #include <stdio.h>
      2 #include <sys/types.h>
      3 #include <unistd.h>
      4 #include <stdlib.h>
      5 
      6 //fork---->孤儿进程,僵尸进程,
      7 
      8 int main(void)
      9 {
     10     pid_t pd = 0;
     11     int status = 0;
     12 
     13     pd = fork();
     14 
     15     if(0 > pd)
     16     {
     17         perror("fork");
     18         exit(EXIT_FAILURE);//--->return 
     19     }
     20 
     21     if(0 == pd)
     22     {
     23         printf("this is child process:%d
    ", getpid());
     24         printf("my parent process id:%d
    ", getppid());
     25         sleep(5);
     26         exit(9);
     27     }
     28     //子进程程序
     29     else if(0 < pd)
     30     //pd > 0
     31     {
     32         wait(&status);//回收子进程资源
     33         printf("status is %d
    ", status>>8);
     34         printf("this is parent process:%d
    ", getpid());
     35         printf("my parent process id:%d
    ", getppid());
     36     }
     37     //父进程程序    
     38 
     39 
     40     return 7;
     41 }
    ~                                                                                                                                                                                  
    ~                

        运行结果:

        

        

        可以看到父进程在5S之后等待子进程退出之后在退出!回收子进程的资源!

        

          

     

        

  • 相关阅读:
    钱多多软件制作04
    团队项目01应用场景
    HDU 4411 arrest
    HDU 4406 GPA
    HDU 3315 My Brute
    HDU 3667 Transportation
    HDU 2676 Matrix
    欧拉回路三水题 POJ 1041 POJ 2230 POJ 1386
    SPOJ 371 BOXES
    POJ 3422 Kaka's Matrix Travels
  • 原文地址:https://www.cnblogs.com/hongzhunzhun/p/4547618.html
Copyright © 2011-2022 走看看