v1 进程概念
1.程序:是静态的,存放在磁盘上的指令和数据的有序集合
进程:动态的,包括创建、调度、执行和消亡
执行一个程序所分配的资源的总称,进程是程序的一次执行过程的总称
2.进程包括代码段、数据段、BSS段、堆、栈、进程控制块(面试中经常问到)
程序包括代码段、数据段、BSS段
BSS:BSS段用来存放程序中未初始化的全局变量的一块区域
数据段:数据段常用来放程序中已初始化全局变量的一块区域
堆:当进程调用malloc函数分配内存时,新分配的内存就会动态分配到堆上
栈:用户存放程序临时创建的局部变量,但不包括static声明的变量
进程控制块:包括进程标识PID,进程用户,进程状态,优先级,文件描述符表
进程的类型:
1、交互类型:在shell下启动,可以在前台运行,也可以在后台运行
2、批处理进程:和在终端无关,被提交到一个作业队列中以便顺序执行
3、守护进程:和终端无关,一直在后台运行
进程状态:
运行态:进程正在运行或者等待运行
等待态:进程在等待一个事件的发生或者某种系统资源(cpu)
停止态:进程被中止,收到信号可继续运行
死亡态(僵尸态):linux独有的状态,已被终止的状态,但pcb仍然没有释放
v2 进程常用命令
ps 查看系统进程快照
top 查看进程动态信息,实时查看
/proc 查看进程详细信息 ls /proc /99
ps -e 会显示进程所有信息
ps -l 长格式显示更加详细的信息
ps -f全部列出,通常和其他选项联用
shift+>是后翻页,shift+<是前翻页
top -p PID查看某个进程 如 :top -p 41
renice 改变进程优先级
jobs 查看后台进程
bg 将挂起的进程在后台运行
fg 1 把后台运行的进程放到前台运行
ctrl+z 把运行的前台进程转为后台并停止
./test & 把程序转为后台运行
v3
v3 创建子进程
除了第一个子进程,其他的都是由他人创建的
shell创建的子进程
创建进程的函数fork
#include <unistd.h>
pid_t fork(void);
创建新的进程,失败时返回-1
成功时父进程返回子进程的进程号,子进程返回0
通过fork的返回值区分父进程和子进程
fork做了哪些事情
复制一份进程A,B和A之间的代码是一模一样的
但是B不会执行A的代码,如果B执行A的代码,那么就会无线fork下去
所以说B只会执行A中代码fork之下的部分,如果在fork之前的代码,子进程也不会执行
B和A执行的代码有啥用呢?
执行完fork函数,会出现一个pid,所以A的pid有值,B的pid值为0
我认为:这个代码的执行顺序是父进程先全部执行一遍,然后回到fork函数下面继续执行代码,此时子进程的pid=0在内存中已经有了,然后接着判断这个pid是否大于0,接着再继续往下执行
实际上:操作系统的父进程,子进程执行顺序是由操作系统调度的
改进之后看的更清楚:
创建子进程:
子进程概念
fork函数
子进程只执行fork以下的代码
父子进程执行顺序由操作系统决定!!! !!
通过ps查看id号来确定哪个是父进程哪个是子进程 ,命令:ps -elf | grep fork _t
pid是子进程的,ppid是父进程的
杀死父进程,子进程就会被init进程回收
kill -9 19426 (19426是父进程的pid,之后19427的ppid就会显示1,1是init的pid)
在父进程存在的情况下,杀死子进程
出现了<defunct>,就说明他已经成为了僵尸进程
v4 子进程进阶
如果说要一个父进程创建五个子进程,理想中的进程应该是这样
但是每次fork一次,子进程也会产生子进程
实际上产生的进程数是这样子的
怎样出现理想状态下的五个进程呢?
在子进程结束后,用break语句表示跳出
产生这个形状的进程,是需要父进程不再产生子进程,在父进程语段里面添加break
v5 进程的退出
void exit (int status) 结束进程时会刷新缓冲区,其他几个函数没有区别
exit代码后面的printf()内容就不会执行了
比如说在这个地方,exit(0)这main函数就已经结束了,而不是到了return 0才算结束
return和exit区别!!!!!
v6 进程的回收
父进程创建子进程,子进程被杀死,没有被回收,就会变成僵尸进程
成功回收的代码: