Day1 进程的创建和回收

目录

一、进程的概念

1、进程内容

2、进程类型

3、进程状态

二、进程常用命令

1、查看进程信息

2、改变进程优先级

3、jobs 查看后台进程

三、创建子进程

四、子进程的进阶

五、进程结束 - exit/ _exit

六、进程的回收

1、进程回收 - wait

2、进程回收 - waitpid


  • 一、进程的概念

  • 程序:
  • 存放在磁盘上的指令和数据的有序集合(文件)
  • 静态的
  • 进程:
  • 执行一个程序所分配的资源的总称
  • 进程是程序的一次执行过程
  • 动态的,包括创建、调度、执行和消亡
  • 程序在RAM里,进程在ROM(磁盘)里
  • 1、进程内容

  • BSS段: BSS段通常是指用来存放程序中为初始化的全局变量的一块内存区域。BSS是英文 Block Started by Symbol的简称。
  • 数据段: 数据段通常是指用来存放程序中已初始化的全局变量的一块内存区域。
  • 代码段: 代码段通常是指用来存放程序执行代码的一块内存区域。这部分区域的大小在程序运行前就已经确定,在代码段中,也有可能包含一些只读的常数变量,例如字符串常量等。
  • 堆(heap):堆适用于存放进程运行中被动态分配的内存段,当进程调用malloc等函数分配内存时,新分配的新村就被动态添加到堆上(堆被扩张);当free等函数释放内存时,被释放的内存从堆中被剔除(堆被缩减)
  • 栈(stack): 栈又称堆栈,是用户存放临时创建的局部变量(但不包括static声明的变量,static意味着在数据段中存放变量),函数参数,函数的返回值。由于栈的先进后出特点,所以栈特别方便用来保存/恢复调用现场。可以把堆栈看成一个寄存、交换临时数据的内存区。
  • 进程控制块(pcb)(管理/存放进程的属性):进程标志PID,进程用户, 进程状态、优先级,文件描述符表
  • 2、进程类型

  • 交互进程: 在shell(前台)下启动。以在前台运行,也可以在后台运行
  • 批处理进程:和在终端无关,被提交到一个作业队列中以便顺序执行
  • 守护进程: 和终端无关,一直在后太运行(后面详细讲)
  • 3、进程状态

  • 运行态: 进程正在运行,或者准备运行
  • 等待态: 进程在等待一个事件的发生或某种系统资源
  • 可中断
  • 不可中断
  • 停状态: 进程被终止,收到信号后可继续运行
  • 死亡态: 以终止的进程, 单pcd没有被释放
  • 二、进程常用命令

  • 1、查看进程信息

  • ps 查看系统进程快照 (ps -e显示所有进程 、ps -elf 显示进程详细信息)
  • top 查看进程动态信息
  • /proc 查看进程详细信息
  • ps 命令详细参数:
  • -e:显示所有进程
  • -l:长格式显示更加详细的信息
  • -f 全部列出,通常和其他选项联用
  • ps -elf|grep 加进程名,可单独查看该名称的进程
  • top 查看进程动态信息
  • shift +> 后翻页
  • shift +< 前翻页
  • top -p PID 查看某个进程
  • 2、改变进程优先级

  • 默认优先级是 0
  • nice 按用户指定的优先级运行进程
  • nice [-n NI值] 命令
  • NI 范围是 -20~19。 数值越大优先级越低
  • 普通用户调整NI值的范围是0~19, 而不能降低。如果原本NI值为0,则之恩那个调整为大于0
  • 只有 root 用户才能设定进程 NI 值为负数,而且九二一调增任何用户的进程
  • renice 改变正在运行进程的优先级
  • renice [优先级] PID
  • 3、jobs 查看后台进程

  • bg 将挂起的进程在后台运行
  • fg 把后台运行的进程放到前台运行
  • ctrl + z 把运行的前台进程转为后台并停止
  • ./test & 把test程序后台运行
  • 三、创建子进程

  • 子进程概念:子进程就是有另外一个进程(对应称之为父进程)所创建的进程
  • 子进程创建 - fork
  • #include <unistd.h>
  • pid_t fork(void);
  • 创建新的进程,失败是返回-1
  • 成功时父进程返回子进程的进程号,子进程返回0
  • 通过fork的返回值区分父进程和子进程
  • 要点:1 虽然全部拷贝了父进程,但子进程只执行fork之后的代码
  •            2. 父子进程执行顺序是操作系统决定的。
  • 结果

  • 子进程继承了父进程的内容
  • 父子进程有独立的地址空间,互不影响
  • 如父进程先结束:
  • 子进程称为孤儿进程,被init进程收养
  • 子进程变成后台进程
  • 若子进程先结束:
  • 父进程如果没有及时回收,子进程变成僵尸进程
  • 如何让子进程执行不同于父进程的内容:
  • 通过判断pid值区分父子进程,从而让他们执行不同的内容。
  • 结果:
  • 使用ps -elf|grep 可查看谁是父子进程(PPID是父进程PID)。下图中10079的PPID是10078。杀死父进程(此时是10078)后,子进程的PPID变为init的PID,被init收养了。此时只会执行子进程,CTRL+c无法结束。因为子进程变为了后台进程。可使用 kill 命令杀死。
  • 杀死子进程后,子进程仍然存在,但是变成了僵尸进程(defunct),此时需要父进程把它火化,(关掉父进程即可,可使用CTRL+c结束)
  • 四、子进程的进阶

  • 1、一个父进程生成五个子进程
  • fork_t1.c:

  • 如果不结束,子进程也会去执行for循环,(子进程只执行fork后内容是有前提的,此时因为本身就是循环,不是按位置执行,是按顺序执行)会创建孙进程
  • 结果:

  • 生成如图所示,上一个进程永远是下一个进程的爹

  • 五、进程结束 - exit/ _exit

  • #include <stdlib.h>
  • #include <unistd.h>
  • void exit(int status);
  • void _exit(int status);
  • void _Exit(int status);
  • 结束当前的结成并将status返回
  • exit结束进程时会刷新(流)缓冲区

  • 而_exit()不会刷新缓冲区

  • return 和exit的区别
  • 只有main函数结束时会隐式地调用exit函数,普通函数return是返回上一级。

  • 六、进程的回收

  • 子进程结束时由父进程回收
  • 孤儿进程由init进程回收
  • 若没有及时回收会出现僵尸进程
  • 1、进程回收 - wait

  • #include <sys/wait.h>
  • pid_t wait(int *status);
  • 成功时返回回收的子进程的进程号,失败时返回EOF
  • 若子进程没有结束,父进程一直阻塞
  • 若有多个子进程,那个先结束就回收哪个
  • status 指定保存子进程返回值和结束方式的地址
  • status为NULL表示直接释放子进程PCB,不接受返回值
  • wait_t.c

  • 结果:wait可以回收僵尸进程

  • 2、进程回收 - waitpid

  • #include <sts/wait.h>
  • pid_t waitpid(pid_t pid, int *status, int option);
  • 成功时返回回收的子进程的pid或0;失败是返回EOF
  • pid可用于指定回收那个子进程或任意子进程
  • status指定用于保存子进程返回值和结束方式的地址
  • option指定回收方式, 0或 WNOHANG
  • 参数:
  • pid
  • pid>0时,只等待进程ID等于pid的子进程,不管其它已经有多少子进程运行结束退出了,只要指定的子进程还没有结束,waitpid就会一直等下去。
  • pid=-1时,等待任何一个子进程退出,没有任何限制,此时waitpid和wait的作用一模一样。
  • pid=0时,等待同一个进程组中的任何子进程,如果子进程已经加入了别的进程组,waitpid不会对它做任何理睬。
  • pid<-1时,等待一个指定进程组中的任何子进程,这个进程组的ID等于pid的绝对值。
  • options
  • options提供了一些额外的选项来控制waitpid,目前在Linux中只支持WNOHANG和WUNTRACED两个选项,这是两个常数,可以用"|"运算符把它们连接起来使用
  • WNOHANG :若由pid指定的子进程未发生状态改变(没有结束),则waitpid()不阻塞,立即返回0
  • WUNTRACED: 返回终止子进程信息和因信号停止的子进程信息
  • wait(wait_stat) 等价于waitpid(-1,wait_stat,0)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值