曲阜网站建设哪家便宜,十大中国网站制作,wordpress博客只显示几个,专业做网站建设制作服务进程概念1 认识冯诺依曼体系结构1.1 冯诺依曼体系结构存储器的作用2 操作系统(Operator System#xff0c;OS)2.1 OS如何进行管理3 进程3.1 OS管理进程#xff1a;先描述再组织3.2 描述进程-PCB3.3 查看进程3.4 通过系统调用获取进程标识符3.5 通过系统调用创建子进程——for…
进程概念1 认识冯诺依曼体系结构1.1 冯诺依曼体系结构存储器的作用2 操作系统(Operator SystemOS)2.1 OS如何进行管理3 进程3.1 OS管理进程先描述再组织3.2 描述进程-PCB3.3 查看进程3.4 通过系统调用获取进程标识符3.5 通过系统调用创建子进程——fork4 进程状态4.1 进程阻塞4.2 挂起状态4.3 僵尸zombie状态4.4 孤儿进程本篇文章所涉及到的内容主要是与
进程的基础概念相关所涉及到的内容有1认识冯诺依曼系统2操作系统的概念与定位3深入了解进程概念了解PCB4会学习到进程状态和创建进程僵尸进程和孤儿进程及其形成的原因和危害1 认识冯诺依曼体系结构
我们的计算机大部分都遵循冯诺依曼体系结构 冯诺依曼体系结构如下图所示 这里的输入设备可以是键盘话筒摄像头鼠标网卡磁盘等 存储器就是我们的内存 输出设备可以是显示器磁盘网卡声卡音响等 中央处理器部分就是我们常说的CPU
1.1 冯诺依曼体系结构存储器的作用
我们首先要知道我们的输入输出设备通常称之为外设而这些外设一般会运行得比较慢以磁盘为例相对于内存磁盘运行是比较慢的。 而我们的CPU运行是最快的。
这里要讨论的是冯诺依曼体系结构中存储器的作用我们尝试去掉存储器。 这种可以运行吗答案是可以的。 但是比起冯诺依曼体系结构效率差的太远了。 因为我们前面说过外设的运行是最慢的而CPU运行的效率虽然快但是外设的运行效率拖慢了CPU的运行效率。换句话就是我输入设备都还没读进来CPU运行得再快也没用CPU怎么处理
所以我们可以得出大致的一个结论 冯诺依曼体系结构中的存储器可以更好地提升整个体系的运行效率。
因为有了内存的存在我们的计算机就可以对数据做预加载CPU在进行数据计算时就可以不用访问外设直接与内存联系即可。 外设要输入输出数据也只能写入内存或从内存中读取
2 操作系统(Operator SystemOS)
操作系统是一款进行软硬件资源管理的软件 操作系统对下通过管理好软硬件资源对上给提供良好的安全稳定高效功能丰富等的执行体验。 如图所示操作系统对外会表现为一个整体但是会暴露自己的部分接口供上层开发使用这部分由操作系统的提供的接口叫做系统调用。 系统调用在使用上功能比较基础对用户的要求相对也比较高所以有心的开发者可以对部分系统调用进行适度封装从而形成库有了库就很有利于更上层用户或者开发者进行二次开发。
2.1 OS如何进行管理
OS管理的手段是先描述再组织 什么意思呢我们要先知道这里的管理的本质是指对被管理对象的数据进行管理 也就说OS是先将所有被管理对象的数据收集起来先描述然后再放在相应的数据结构里面再组织以方便进行后续的操作。
3 进程
什么是进程 我们通常说进程是程序的一个执行实例。一个正在执行的程序等 站在内核的角度来说进程是担当分配系统资源(CPU时间内存)的实体
3.1 OS管理进程先描述再组织
我们任何启动程序的行为都由操作系统帮助我们将程序转换为进程完成特定的任务。
OS如何管理进程 还是先描述再组织
3.2 描述进程-PCB
进程控制块PCBProcess Control Block进程信息被放在这样的数据结构中可以理解为进程属性的集合。 Linux操作系统的下的PCB是task_struct task_struct是Linux内核的一种数据结构它会被装载到RAM(内存)里并且包含着进程的信息。
所以 进程 内核关于进程的相关数据结构 当前的代码和数据
3.3 查看进程
进程的信息可以通过/proc系统文件夹查看 如要获取PID为1的进程信息你需要查看/proc/1这个文件夹
大多数进程信息同样可以使用top和ps这些用户级工具来获取
我们写出这样一段C语言代码并运行它 输入
ps axj | head -1 ps ajx | grep xxx| grep -v grep//xxx是可执行文件名称即可查看该程序的进程
3.4 通过系统调用获取进程标识符
每个进程都会有对应的PID进程id也会有PPID父进程id 我们反复运行可以看到每次运行该程序的PID都不同而父进程的ID都是一样的。 这里的父进程其实是bash我们输入以下命令查看2707进程信息
ps axj | head -1 ps ajx | grep 2707这里说明了bash命令行解释器本质上也是一个进程
3.5 通过系统调用创建子进程——fork
我们运行一下这段代码
#include stdio.h
#include sys/types.h
#include unistd.h
int main()
{int ret fork();printf(hello proc : %d!, ret: %d\n, getpid(), ret);sleep(1);return 0;
}我们发现会发现打印了两行说明该程序利用fork()创建了两个进程而且是父子进程的关系。 fork有两个返回值 父子进程代码共享数据各自开辟空间私有一份采用写时拷贝 fork 之后通常要用 if 进行分流 当fork返回值是0时是子进程。 fork返回值大于0时是父进程。 我们写一段代码验证一下 可以明显地看到fork出来的两个进程确实是父子进程的关系。 子进程的ppid一直都是父进程的pid父进程的ppid也一直是bash的pid
4 进程状态
进程除了运行状态还会有其他的状态。 我们看一下下面的状态在kernel源代码里的定义
/*
* The task state array is a strange bitmap of
* reasons to sleep. Thus running is zero, and
* you can test for combinations of others with
* simple bit tests.
*/
static const char * const task_state_array[] {
R (running), /* 0 */
S (sleeping), /* 1 */
D (disk sleep), /* 2 */
T (stopped), /* 4 */
t (tracing stop), /* 8 */
X (dead), /* 16 */
Z (zombie), /* 32 */
};R运行状态running:其实运行状态并不代表该进程一定在运行中它表明进程要么是在运行中或者是在运行队列里。因为在CPU在计算进程时是将多个进程快速切换并逐一运行的不是同时运行的多个进程像队列一样排好队等待CPU计算。因为快速切换的时间非常短所以我们人很难感觉到。 S睡眠状态sleeping:意味着程序在等待事件的完成。这里的睡眠有时候也叫做可中断睡眠interruptible sleep。这里的睡眠状态本质上是一种阻塞状态。 D磁盘休眠状态Disk sleep有时候也叫不可中断睡眠状态uninterruptible sleep在这个状态的进程通常会等待IO的结束。 T停止状态stopped 可以通过发送 SIGSTOP 信号给进程来停止T进程。这个被暂停的进程可以通过发送 SIGCONT 信号让进程继续运行。 X死亡状态dead这个状态只是一个返回状态你不会在任务列表里看到这个状态。
4.1 进程阻塞
进程阻塞是一种因为要等待某种条件就绪而导致的一种不可推进的状态。 说的简单一点就是该进程需要某种资源才能运行否则就会卡住。 CPU要处理大量的进程上面说过OS要做进程进行管理管理方式就是先描述再组织。而我们的PCB可以被维护在不同的队列中这些队列中都是一个个要被运行的进程正在排队等待运行的进程的状态可以看成阻塞状态。或者拿我们的外设键盘来说如果我们执行了一个需要我们输入后才能运行的程序在程序等待我们输入的过程中这个过程就是阻塞状态并不是运行状态。OS会创建一个相应的结构体task_struct去描述并组织管理这个进程。 所以阻塞就是不被调度一定是因为当前进程需要某种资源进程task_struct结构体需要在某种被OS管理的资源下排队。
4.2 挂起状态
前面我们说过当进程阻塞时就是不被CPU调度那么此时该进程会在内存里面占有一定的空间如果这种进程非常多的话就会影响正常的进程运行所以我们的OS会把这种不被调度的进程的代码和数据放在磁盘中这种状态就叫做挂起状态也可以说挂起阻塞状态。
4.3 僵尸zombie状态
僵尸状态Z状态可以和死亡状态(X状态)联系起来。 如果一个进程退出了那么它会马上进入X状态立即退出那么由于写时拷贝的原因我们的父进程可能会没有机会拿到子进程的退出结果。所以Linux当进程退出的时候一般进程不会立即进入X状态而是要维持Z状态方便后续父进程或者OS读取该子进程退出的结果。
僵尸进程的危害可能会造成内存泄漏。 一个进程的退出状态要一直被维持下去直到父进程读取它的信息。如果父进程一直没有读取它的信息那么该子进程就会一直维持僵尸状态。维护退出状态本身就是要用数据维护也属于进程的基本信息所以保存在PCB中Z进程不退出PCB要一直维护如果有大量的这种不被读取信息的进程不被回收就会造成内存资源的浪费导致内存泄漏。
如果在没有特殊要求的情况一个父进程结束后会被bash回收所以我们一般不会直接看到Z状态。
4.4 孤儿进程
如果一个父进程退出而它的子进程还在这个子进程会自动被1号进程领养这个1号进程就是我们的OS1号进程成为这个子进程的父进程这种被领养的进程就叫做孤儿进程。 如果没有这种领养机制那么子进程后续在退出的时候就没有父进程可以回收了可能会浪费掉内存这是不被OS认可的所以OS会领养这种没有父进程的子进程。