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

 

一.进程

     

进程是正在执行的程序实例。执行程序时,内核会将程序代码载入虚拟内存,为程序变量分配空间,在内核中建立相应的数据结构,以记录与进程有关的各种信息(比如,进程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之后等待子进程退出之后在退出!回收子进程的资源!

    

      

 

    

时间: 2024-10-24 04:41:43

系统编程之进程的创建.僵尸与孤儿进程的相关文章

戏说守护、僵尸、孤儿进程

首先说简单的结论: 没有父进程的进程就是孤儿进程,孤儿进程会被init领养,成为一个准守护进程. 如果进程他爹活着,但是不给子进程收尸(wait.waitpid),子进程就会变成僵尸. 守护进程(Daemon)是在一类脱离终端在后台执行的程序, 通常以 d 结尾, 随系统启动, 其父进程 (ppid) 通常是 init 进程 以下是Wikipedia中关于Daemon的定义: In multitasking computer operating systems, a daemon (/dimn/

Linux系统编程之--守护进程的创建和详解【转】

本文转载自:http://www.cnblogs.com/mickole/p/3188321.html 一,守护进程概述 Linux Daemon(守护进程)是运行在后台的一种特殊进程.它独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件.它不需要用户输入就能运行而且提供某种服务,不是对整个系统就是对某个用户程序提供服务.Linux系统的大多数服务器就是通过守护进程实现的.常见的守护进程包括系统日志进程syslogd. web服务器httpd.邮件服务器sendmail和数据库服务器

Python并发编程03/僵尸孤儿进程,互斥锁,进程之间的通信

目录 Python并发编程03/僵尸孤儿进程,互斥锁,进程之间的通信 1.昨日回顾 2.僵尸进程和孤儿进程 2.1僵尸进程 2.2孤儿进程 2.3僵尸进程如何解决? 3.互斥锁,锁 3.1互斥锁的应用 3.2Lock与join的区别 4.进程之间的通信 进程在内存级别是隔离的 4.1基于文件通信 (抢票系统) 4.2基于队列通信 Python并发编程03/僵尸孤儿进程,互斥锁,进程之间的通信 1.昨日回顾 1.创建进程的两种方式: 函数, 类. 2.pid: os.getpid() os.get

Linux系统编程——特殊进程之守护进程

什么是守护进程? 守护进程(Daemon Process),也就是通常说的 Daemon 进程(精灵进程),是 Linux 中的后台服务进程.它是一个生存期较长的进程,通常独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件. 守护进程是个特殊的孤儿进程,这种进程脱离终端,为什么要脱离终端呢?之所以脱离于终端是为了避免进程被任何终端所产生的信息所打断,其在执行过程中的信息也不在任何终端上显示.由于在 Linux 中,每一个系统与用户进行交流的界面称为终端,每一个从此终端开始运行的进程都

06.系统编程-1.进程

1.多任务的引入 实现类似唱歌又跳舞的任务同时进行的,叫做:多任务 2.多任务的概念 什么叫"多任务".简单地说, 就是操作系统可以同时运行多个任务. 单核CPU执行多任务,就是操作系统轮流让各个任务交替执行,任务1执行0.01秒, 切换到任务2,任务2执行0.01秒,再切换到任务3, 执行0.01秒--这样反复执行下去.每个任务都是交替执行的,但是,由于CPU的执行速度实在是太快了, 我们感觉就像所有任务都在同时执行一样. 真正的并行执行多任务只能在多核CPU上实现,但是,由于任务数

孤儿进程、僵尸进程和守护进程

维基百科的解释中: 在操作系统领域中,孤儿进程指的是在其父进程执行完成或被终止 后仍继续运行的一类进程. 在类UNIX系统中,僵尸进程是指完成执行(通过 exit 系统调用,或运行时发生致命错误或收到终止信号所致)但在操作系统的进程表中仍然有一个表项(进程控制块PCB),处于"终止状态 "的进程. 在一個多工的電腦作業系統中,守护进程(英语:daemon,英语发音:/?di?m?n/或英语发音:/?de?m?n/)是一種在后台执行的电脑程序. 此类程序会被以进程的形式初始化. 守护进程

linux系统编程视频 百度网盘下载

本帖最后由 雇佣兵333 于 2015-5-19 16:15 编辑 c教程目录: Linux开发快速入门培训gcc快速入门Makefile快速入门GDB快速入门 Linux系统编程之文件篇01认识计算机系统(上)计算机系统组成计算机系统硬件组成总线I/O设备内存处理器(运算器+控制器) 02认识计算机系统(下)什么是操作系统Linux内核模块操作系统管理硬件操作系统三个基本抽象进程上下文切换进程虚地址空间虚拟文件系统(VFS) 03系统编程介绍系统编程与应用编程系统资源系统调用系统调用与C库关系

zombie僵尸进程、孤儿进程和守护进程

以前一直对僵尸进程和孤儿进程都没怎么理解,真是罪过,最近在看liunx编程设计(第四版),看到了他们的概念,所以对它们做个总结!加深印象. 基本概念: 我们知道在unix/linux中,正常情况下,子进程是通过父进程创建的,子进程再创建新的进程.子进程的结束和父进程的运行是一个异步过程,即父进程永远无法预测子进程 到底什么时候结束. 当一个 进程完成它的工作终止之后,它的父进程需要调用wait()或者waitpid()系统调用取得子进程的终止状态. 但是如果情况不是这样的会怎么样呢,毕竟世事难料

Linux中的僵尸进程和孤儿进程

在UNIX里,除了进程0(即PID=0的交换进程,Swapper Process)以外的所有进程都是由其他进程使用系统调用fork创建的,这里调用fork创建新进程的进程即为父进程,而相对应的为其创建出的进程则为子进程,因而除了进程0以外的进程都只有一个父进程,但一个进程可以有多个子进程.        操作系统内核以进程标识符(Process Identifier,即PID)来识别进程.进程0是系统引导时创建的一个特殊进程,在其调用fork创建出一个子进程(即PID=1的进程1,又称init)