什么是进程?
书本概念:程序的一个执行实例,正在执行的程序等
内核观点:担当分配系统资源(CPU时间,内存)的实体
如何描述进程?
进程信息被放在一个叫做进程控制块的数据结构中,可以理解为进程属性的集合。
进程控制块也叫 PCB 进程控制块,Linux下称为 task_struct。
task_struct 是一个很大的结构体,包含许多内容,一个进程对应一个task_struct。
一般从下面几个方面描述一个进程(信息都包含在task_struct中):
- 标示符: (pid)描述本进程的唯一标示符,用来区别其他进程。
- 状态: 任务状态,退出代码,退出信号等。
任务状态:
R 就绪状态:进程在就绪队列中,就会处于这个状态
S 睡眠状态:进程不在运行状态,且不在就绪队列中
D 深度睡眠状态(临死状态):密集的进行 IO 操作的时候(吐coredump的状态)
T 暂停状态:stop (Ctrl + z) 将进程放在了后台,默认不运行
t 跟踪状态:trace
X 进程已经结束:只是在Linux源码中存在,真实是看不到的
Z 僵尸进程:和父进程,子进程相关联
僵尸进程:
成因:子进程结束后,父进程没有回收子进程的资源,为了解决子进程像父进程汇报工作的问题
危害:内存泄漏
处理:直接kill 僵尸进程是kill 不掉的,可以kill 掉僵尸进程的父进程(临时处理)
kill 掉僵尸进程的父进程之后,僵尸进程就变成的孤儿进程,此时孤儿进程被 1号进程收养,从而释放资源
更科学的处理:进程等待(wait)
优先级:数字,表示这个进程是先被执行还是后被执行
top命令:
PR显示优先级
NI(nice)优先级的修正值。PR+NI=最终的PR
通过指令可以调整nice值,宏观上看不出效果
数字越小,优先级越高
上下文(寄存器):
进程执行时处理器的寄存器,执行速度很快,宏观上用户感觉不到,类似于游戏存档,
保存上下文就是CPU寄存器的内容保存到内存中,恢复上下文,内存中的寄存器值恢复到CPU中
记账信息:
每个进程已经在CPU上执行了多久的统计数据,可能包括处理器时间总和,使用的时钟数总和,时间限制,记账号等
进程的调度 :让少量的CPU能够满足大量的进程同时执行的需求
并行:两个CPU分别执行两个进程
并发:一个CPU分别执行两个进程
如何查看进程(进程和可执行程序没啥关联)
相关操作命令:
ps:相当于任务管理器,能够查看系统上有哪些进程
ps aux 查看所有进程
ps aux | less 配合less进行翻页查看和其他操作
ps aux | grep [进程名] 查看匹配过程
组织进程
双向链表进行组织,每个节点就是一个task_struct,可以在内核源代码里找到它。所有运行在系统里的进程都以task_struct链表的形式存在内核里
创建子进程
fork:使用代码来创建子进程:fork()函数创建
1,返回值:一次调用两个返回值(父进程,子进程)
getpid 获取进程ID
getppid 获取父进程ID
父进程返回子进程的ID
子进程返回0
通常需要让父子进程执行不同的逻辑,就可以借助fork的返回值进行区分
如果失败,返回<0 的结果,失败原因:
1> 内存不够
2> 进程太多,达到上限
3> RLMIT_NPROC
2,执行过程:父子进程都是紧接着fork继续执行
3,先后顺序:不确定,取决于操作系统的调度器
#include<stdio.h>
#include<unistd.h>
int main()
{
pid_t id = fork();
if(id > 0){
//parent
printf("parent: %d\n",getpid());
}
else if(id == 0){
//children
printf("children: %d\n",getpid());
}
else
perror("fork");
sleep(1);
return 0;
}