Linux:认识进程
说到进程,我们首先要来认识一下冯诺依曼体系结构它也被称为现代计算机硬件体系结构,包括:
- 输入设备:如键盘/鼠标
- 输出设备:如显示器/打印机
- 存储器:如内存-外存
- 运算器/控制器:这两个功能都由CPU来实现。
举一个生活中常见的情形:如果你要用电脑通过qq给小明发消息,那麽你一定要先将这条信息通过键盘输入进你的电脑,存储进内存后,CPU取出这条信息,通过网卡等设备将它输送到小明的电脑,他的电脑也将这段文本先存储起来,再由CPU调用打印到荧屏上,所以我们说硬件结构决定了软件行为,硬件结构决定数据流向
那么什么是进程呢?
- 进程是一个运行中的程序,Linux是一个多任务操作系统,表示有大量的程序需要被pcb调度运行,这时cpu使用了分时技术(切换调度运行,每个程序只运行很短一段时间(时间片)),分别轮询处理每一个程序,在进程程序切换调度时,需要记录运行信息,因此操作系统在调度进程在cpu上运行时,使用PCB对运行中的程序进行描述,通过调度PCB完成对进程的调度,因此进程是PCB(进程描述符)
-
一句话概括:使用PCB描述进程,使用双向链表将PCB串起来进行管理;先描述后组织
- PCB->task_struct基础描述信息:
- 内存指针:通过内存指针来访问存储该程序的内存位置;
- 程序计数器:程序中即将被执行的下一条指令的地址;
- 上下文数据:进程执行时处理器的寄存器中的数据;
- 标识符PID: 描述本进程的唯一标示符,用来区别其他进程;
- 进程状态: 任务状态,退出代码,退出信号等;
- 优先级–交互式进程/批处理进程-交互式进程更优先;
- IO状态信息: 包括显示的I/O请求,分配给进程的I/O设备和被进程使用的文件列表;
- 记账信息: 可能包括处理器时间总和,使用的时钟数总和,时间限制,记账号等;
进程状态
Linux下的进程从创建到销毁根据特质行为的不同也分为多达七种状态:
- 运行态( R):正在运行的进程,或者一拿到时间片就可以运行的状态
- 可中断睡眠态(S): 意味着进程在等待事件完成;
- 不可中断睡眠态(D): 在这个状态的进程通常会等待IO的结束,睡眠也是一个动作
- 停止态(T): 可以通过发送 SIGSTOP 信号给进程来停止(T)进程。这个被暂停的进程可以通过发送 SIGCONT 信号让进程继续运行。但在停止时没有任何动作
- 僵死态(Z):进程退出了,但资源没有完全释放(没有完全退出
- 死亡态(X):进程退出的一瞬间,这个状态只是一个返回状态,你不会在任务列表里看到这个状态,
- 追踪态(t):
进程的创建与退出
作为管理者,我们当然也要熟悉如何创建和退出进程
进程创建:
- 作用:分摊压力,cpu资源足够情况下父子进程同时处理数据,效率高;/代码分流-干其他的事)
-
fork–通过复制调用进程(父进程)创建一个新的进程(子进程)
- 复制了父进程的pcb(意味着和父进程拥有一样的内存指针/程序计数器/上下文数据)
- 和父进程运行相同的代码,一样的运行位置;处理一样的数据
- 父子进程代码共享,数据独有
- 复制了父进程的pcb(意味着和父进程拥有一样的内存指针/程序计数器/上下文数据)
如何分辨一个父子进程?
- 通过返回值分辨
- 父进程调用fork():返回子进程的pid,pid>0
- 子进程调用fork():返回0;
- fork()失败:返回-1;
- vfork():创建子进程—子进程与父进程共用同一块虚拟地址空间,为了防止调用栈混乱,因此阻塞父进程直到子进程调用exit()退出或者进行程序替换。
- vfork的子进程不能在main函数中return退出,因为会连父进程的资源也一起释放了,父进程会陷入混乱崩溃;
- fork与vfork在内核都是调用clone实现进程创建;
进程退出:
- 进程退出场景:1.正常退出,结果符合预期;2.正常退出,结果不符合预期3.异常退出(crash),当异常退出时会返回一个1~255的异常码,正常退出则返回0;
- 终止方式:
- main函数中return
- exit(int statu) /库函数退出时刷新缓冲区;
- _exit(int statu)->系统调用接口在退出时并不刷新缓冲区,直接释放资源;
- 进程等待: 等待子进程退出—为了避免产生僵尸进程;
- pid_t wait(int *status);//阻塞函数
- 阻塞等待任意一个子进程退出,如果当前没有子进程退出,则一直等待;
- status:用于获取子进程退出码,不关注置空即可
- 返回值:退出的子进程的pid
- 如果等待的进程没有子进程,操作系统自动检测返回
- pid_t waitpid(pid_t pid,int *status,int options)
- pid:等待一个指定子进程(>0)/任意子进程退出(-1);
- options:
- 0 阻塞等待子进程退出
- WNOHANG 将waitpid设置为非阻塞;
- 返回值:>0:退出子进程pid;==0:当前没有子进程退出(非阻塞);<0:出错;
- 阻塞:发起一个系统调用完成功能,当前如果不具备完成条件;则顶戴直到完成功能后返回;
- 非阻塞:当前如果不具备完成条件;则立即报错返回;
- pid_t wait(int *status);//阻塞函数
- 获取退出码
- 核心转储(core dump):程序异常退出时,保存程序的运行信息;系统默认不开放该接口,因为不安全。
- 获取退出码:因为拿到的是一个4个字节的数据,所以我们需要将这个数据先按位右移8位再获取第八位就可以了—(statu>>8)&0xff
- 获取异常退出信号值:statu&0x7f
- 异常退出信号值为0表示子进程正常退出;否则是异常退出,返回值没有判断意义;
yo~
yo~
如果觉得不错~
请别忘了点个赞~
Bro你的鼓励~
给我坚持的勇气~
Peace out~