进程基本概念:
1.进程:
程序:存放在外存中的一段数据组成的文件
进程:是一个程序动态执行的过程,包括进程的创建、进程的调度、进程的消亡
2.进程相关命令:
1.top
动态查看当前系统中的所有进程信息(根据CPU占用率排序)
PID:唯一识别进程的ID号(>0)
优先级:Linux系统中数据低,优先级高(-20 - 19) , Windows系统中数值高,优先级高
进程状态:
R 运行态/就绪态
S 睡眠态/可唤醒等待态
D 不可唤醒等待态
T 暂停态
Z 僵尸态
X 结束态
q退出
2.nice
以指定优先级来运行进程 eg:nice -n 优先级 要执行的集成任务
renice
重新设定一个正在运行的进程的优先级 eg:renice -n 优先级 进程PID
3.kill
杀死指定的进程任务 eg:kill -9 进程PID
killall
杀死进程名对应的所有进程任务 eg:killall -9 进程名
4.ps -ef
查看当前时刻所有进程的信息
PPID:父进程的ID号
ps -ef | grep a.out
5.pstree
查看进程树关系
6.ps -aux
查看当前时刻的进程信息
7../a.out &
将a.out任务放在后台执行
8.jobs
查看一个终端下后台执行的所有任务
9.fg 编号
将后台任务放到前台执行
3.进程的创建
32bits
一个进程在运行时,操作系统会为该进程分配 0 - 4G 虚拟内存空间,分为文本段、数据段、系统数据段
文本段:
也称为文本区,存放代码和指令
数据段:
也称为数据区,可以细分为:
1.字符串常量区
2.未初始化全局变量/静态变量
3.已初始化全局变量/静态变量
系统数据段:
包含堆区和栈区
4.进程中虚拟地址和物理地址的关系
1. 0 - 4G虚拟内存空间只有一个
2. 实际物理地址中每个进程空间独立
3. 通过MMU内存映射单元,单一个进程执行时,将物理地址中的数据加载到虚拟地址中运行
进程
5.常见的调度算法:
1.先来先执行,后来后执行
2.高优先级调度算法
3.时间片轮转调度算法(常用的)
4.多级队列反馈调度算法
5.负载均衡调度算法
时间片:
1.CPU在一个任务中的运行时间称为一个时间片
时间片轮转调度:
1.宏观并行,微观穿行 -- 宏观上是一起执行文件,微观上是执行文件1,进行中断,并保护现场,
去执行2,中断,保护现场,去执行3....后回到文件1,恢复现场,接着执行....
2.每条程序的执行时间有限度,称为时间片,达到时间片的限度后跳转执行,若在限度之内执行完后跳转。跳转的文件根据文件的优先级来进行轮转。
3.保护现场是由PCB进程控制块存储,每一个文件进程度的存储都由PCB进程控制块保存,链表方式连接。
进程的状态:
R 运行态,就绪态
S 睡眠态/可唤醒等待态 eg:等待用户输入
D 不可唤醒等待态 eg:U盘的插拔
T 暂停态
Z 僵尸态 (程序结束了,但是空间还没有被回收)
X 结束态
6.进程相关的函数接口:
1.进程的创建
fork
pid_t fork(void);
功能:
创建一个子进程,新创建的进程称为原来进程的子进程,原来的进程称为新进程的父进程
参数:
void 缺省
返回值:
成功子进程返回0
父进程返回子进程的PID
失败返回-1
父进程调用fork创建子进程,子进程拷贝父进程的文本段、数据段、系统数据段
注意:不可以连用fork,会造成子进程拷贝两个fork,相当于四个进程。
getpid
pid_t getpid(void);
功能:
获得调用进程的PID号
getppid
pid_t getppid(void);
功能:
获得调用进程的PPID
创建一个父进程的2个子进程,子进程中打印自己的PID和父进程的PID,父进程中打印自己的PID和两个子进程的PID:
int main(void)
{pid_t pid;pid_t pid1;pid = fork();if(pid == -1){perror("fail to fork");return -1;}if(pid == 0){printf("z1 pid:%d ,fu pid:%d\n",getpid(),getppid());}else if(pid > 0){pid1 = fork();if(pid1 == -1){perror("fail to fork1");return -1;}if(pid1 == 0){printf("z2 pid:%d ,fu pid:%d\n",getpid(),getppid());}else if(pid1 > 0){printf("fu pid :%d ,z1pid:%d , z2pid:%d\n",getpid(),pid,pid1);}}while(1){}
return 0;}
注意:要加\n出缓存区,不然就会一直输出的内容就会一直在缓存区
2.进程的结束
exit
void exit(int status);
功能:
让进程结束
参数:
status:进程结束的状态
返回值:
缺省
exit在主函数中使用和return效果一致
exit会刷新缓存区
_exit
void _exit(int status);
功能:
让进程直接结束
参数:
status:进程结束的状态
返回值:
缺省
7.进程的消亡
1.僵尸进程:
进程代码执行结束,空间没有被回收,称为僵尸进程
2.如何避免产生僵尸进程?
1.让父进程先结束
2.让父进程回收子进程空间
3.孤儿进程:
进程的父进程先结束,此时该进程称为孤儿进程,被系统进程收养,进程再结束时,会被系统进程回收进程空间
8.wait
pid_t wait(int *wstatus);
功能:
回收子进程空间
参数:
wstatus:存放子进程结束状态空间的首地址
返回值:
成功返回回收到的子进程PID
失败返回-1
1.wait函数具有阻塞功能
2.wait函数具有同步功能
WIFEXITED(wstatus)
进程是否正常退出
WEXITSTATUS(wstatus)
进程结束状态值
WIFSIGNALED(wstatus)
进程是否被信号杀死
WTERMSIG(wstatus)
获得杀死进程的信号编号