操作系统之进程的基础知识

操作系统包括内核(进程管理,内存管理,文件管理,驱动管理)和其它程序(函数库,shell程序等)

设计OS的目的:与硬件交互,管理所有软硬件资源和为用户程序(应用程序)提供一个良好的执行环境。

定位:在整个计算机软硬件架构中,操作系统的定位是:一款纯正的搞管理的软件。

计算机管理硬件:描述起来,用struct结构体,组织起来,用链表或其他高效的数据结构,这样就会形成一个进程队列;

系统调用:在开发角度,操作系统对外会表现一个整体,但是会暴露自己的部分接口,供上层开发使用,这部分由操作系统提供的接口,叫系统调用。

系统调用在使用上,功能比较基础,对用户的要求相对也比较高,所以,有心的开发者可以对部分系统调用进行适度封装,从而形成库,有了库,就很有利于更上层用户或者开发者进行二次开发;

那操作系统是怎么管理进程的呢,很简单,先把进程描述起来,再把进程组织起来!

进程:程序的一个执行实例,这是从宏观上看到的。

内核观点:担当分配系统资源(CPU时间,内存)的实体;

描述进程:进程信息被放在一个叫做进程控制块的数据结构中,可以理解为进程属性的集合,我们课本上称之为PCB(process control block),linux操作系统下的PCB是:task struct(这是进程结构体的名字).

在linux中描述进程的结构体叫做task_struct.

task_struct是linux内核的一种数据结构,它会被装载到RAM(内存)里并且包含着进程的信息。

task_struct的内容分类

标识符:描述本进程的唯一标识符,用来区别其他进程,即就是身份;

进程的状态:任务状态,退出码,退出信号等

进程执行的先后顺序即优先级:相对于其他进程的优先级;

程序计数器:程序中即将被执行的下一条指令的地址。

内存指针:包括程序代码和进程相关数据的指针,还有和其他进程共享的内存块的指针。

上下文数据:进程执行时处理器的寄存器中的数据。

I/O状态信息:包括显示的I/O请求,分配给进程的I/O设备,和被进程使用的文件列表。

记账信息:可能包括处理器时间总和,使用的时钟数总和,时间限制,记账号等。

其他信息;

以上的这些信息其实我们都是用一个结构体来描述的,在Linux下,描述进程的结构体名叫做task_struct。

组织进程:我们可以在内核源代码里找到它,所有运行在系统里的进程都以task_struct(结构体名)链表的形式存在内核里。

查看进程:进程的信息可以通过/proc系统文件夹查看。

我们可以通过系统调用来获取进程标识符。

那我们其实也可以通过系统调用创建进程,用fork()函数,谁创建的谁就是父进程,

创建进程后,父子进程代码共享,数据各自开辟空间,即就是task_struct私有一份。

进程的状态:为了弄明白正在运行的进程是什么意思,我们需要知道进程的不同状态,一个进程可以有几个状态,在linux内核里,进程有时候也叫做任务。

R:运行状态:并不意味着进程一定在运行中,它表明进程要么是在运行中要么在运行队列里。

S:睡眠状态:意味着进程在等待事件完成(这里的睡眠有时候也叫做可中断睡眠状态) 

D:磁盘休眠状态:有时候也叫做不可中断睡眠 状态,在这个状态的进程通常会等待I/O的结束。

T:停止状态:可以通过发送SIGSTOP信号给进程来停止(T)进程,这个被暂停的进程可以通过发送SIGCONT信号让进程继续运行。

X:死亡状态:这个状态只是一个返回状态,你不会在任务列表里看到这个状态。

Z:僵尸进程:其是一个比较特殊的状态。但进程退出并且父进程没有读取到子进程退出的返回代码时就会产生僵尸进程。

僵尸进程会以终止状态保持在进程表即就是task_struct结构体中,并且会一直在等待父进程读取退出状态代码。所以,只要子进程退出,父进程还在运行,但父进程没有读取子进程状态,这是子进程进入Z状态。

僵尸进程的危害:进程的退出状态必须被维持下去,因为他要告诉关心他的进程,你交给我的任务,我办的怎么样了,可父进程如果一直不读取,那子进程就一直处Z状态。维护退出状态本身就是要用数据维护,也属于进程基本信息,它保存在task_struct中,换句话说,Z状态一直不退出,PCB一直都要维护。那一个父进程创建了很多子进程,但就是不回收,是不是就会造成内存资源浪费呢,是的,因为数据结构对象本身就要占用内存,所以这样就会造成内存泄漏!

孤儿进程:父进程先退出,子进程后退出,这时子进程的退出状态没法被父进程获取,我们将这个子进程称之为孤儿进程。

那此时这个孤儿进程怎么办呢?此时他就会被1号进程领养。








猜你喜欢

转载自blog.csdn.net/weixin_40797414/article/details/80368341