您的位置:首页 > 编程语言

系统编程之进程的创建.僵尸与孤儿进程

2015-06-02 20:50 483 查看
 

一.进程

     

进程是正在执行的程序实例。执行程序时,内核会将程序代码载入虚拟内存,为程序变量分配空间,在内核中建立相应的数据结构,以记录与进程有关的各种信息(比如,进程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\n", self_pid);
12     printf("parent_pid = %d\n", 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\n");
10     system("pwd");
11     printf("Over\n");
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\n");
10     execlp("ls","ls","-l", (char *)0);
11     printf("Over\n");
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\n", getpid());
24         printf("my parent process id:%d\n", 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\n", status>>8);
34         printf("this is parent process:%d\n", getpid());
35         printf("my parent process id:%d\n", 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\n", getpid());
24         printf("my parent process id:%d\n", 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\n", status>>8);
34         printf("this is parent process:%d\n", getpid());
35         printf("my parent process id:%d\n", 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\n", getpid());
24         printf("my parent process id:%d\n", 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\n", status>>8);
34         printf("this is parent process:%d\n", getpid());
35         printf("my parent process id:%d\n", getppid());
36     }
37     //父进程程序
38
39
40     return 7;
41 }
~
~


    运行结果:

    


    


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

    

      



 

    
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: