百度网站优点,抖音代运营商家谈判话术,4399网页游戏开服表,网站目录权限设置 user目录 存储管理
linux内存管理基本框架 系统空间管理和用户空间管理
进程与进程调度
进程四要素
用户堆栈的扩展
进程三部曲#xff1a;创建#xff0c;执行#xff0c;消亡
系统调用exit(),wait()
内核中的互斥操作 存储管理
linux内存管理基本框架 系统空间管理…目录 存储管理
linux内存管理基本框架 系统空间管理和用户空间管理
进程与进程调度
进程四要素
用户堆栈的扩展
进程三部曲创建执行消亡
系统调用exit(),wait()
内核中的互斥操作 存储管理
linux内存管理基本框架 系统空间管理和用户空间管理 所以对于系统空间而言虚拟地址到物理地址的映射关系。给定一个虚拟地址x其物理地址是x-PAGE_OFFSET给定一个物理地址起虚拟地址为x PAGE_OFFSET 我们刚刚讲完段式映射和页式映射怎么会有上面的虚拟地址到物理地址的映射关系呢 其实这是一个单独设立的映射只是对系统空间而言是这么管理的 而对于用户空间则还是进行段映射和页映射。 因为每个进程都是独自拥有自己的用户空间3G系统空间却是所有进程共享的。 后面介绍页面管理中的页面换入换出分配撤销都是对用户虚拟空间进行不考虑系统空间因为系统空间已经创建基本不存在换入换出问题除进程控制块的创建与撤销。 所以这里就理解为系统空间的映射关系为虚拟地址到物理地址的映射关系而用户空间的映射就是接下来我们要讲的段映射和页映射的全过程。 我们要讲的段映射和页映射的全过程。
虚拟地址存在于进程创建时系统分配的进程控制块中通过段映射得到线性地址。线性地址通过页映射得到物理地址
linux巧妙的忽略了段式管理的作用而直接使用分页管理具体的实现过程是这样的。将段地址描述结构中的基地址统一设置成0这样虚拟地址就等同于线性地址然后直接转换成物理地址进程与进程调度
相信学过操作系统的同学都知道进程这个概念但肯定有一部分同学无法说清楚进程是什么只知道进程是程序运行的一个实例。的确在我学完操作系统课程之后我依然无法说清楚进程是什么直到我看了计算机系统这本书我才有了一个概念那就是进程不是什么它是一个抽象的概念文件其实也是一个抽闲的概念一张图让我明白进程这个概念。
进程四要素 然后此书上给出进程的四要素让我对进程有了一个更深的理解 1有一段程序供其执行这段程序不一定是进程所专有可以与其他进程公用 2有前面的“私有财产”,就是进程专用的系统堆栈空间。系统空间不是独立的任何进程不能直接改变系统空间的内容除自身的系统堆栈空间 3有“户口”每一个进程都必须有一个task_struct数据结构有了这个结构才能成为内核调度的一个基本单位接收内核调度这个结构记录着进程所占用的各项资源。 4有独立的用户空间这部分是供进程独自占有的 然后书中有这么一段话帮助大家度进程和线程有一个了解缺少上面的任何一条都不能称为进程如果只具备前面3条那就称为线程如果完全没有用户空间就称为“内核线程”而如果是共享用户空间则称为“用户线程”。 但是注意不要把这里的“线程”与有些系统中在用户空间的同一进程内实现的“线程”相混淆。那种线程显然不拥有独立、专用的系统堆栈也不作为一个调度单位接收内核调度。
其中系统空间堆栈用于分配下面2页内容 其中非常有必要介绍一下进程控制块task_struct数据结构里面包含了一个进程各种信息进程调度得以实现绝大功劳归功于进程控制块
注意系统空间堆栈的空间不像用户堆栈那样可以在运行时动态扩展而是静态的确定了的。所以在中断服务程序内核软中断服务程序以及设备驱动程序的设计中应该注意不然这些函数嵌套太深。同时这些函数也避免使用太多太大局部变量。
用户堆栈的扩展 越界访问其中一种情况——相应的页面目录项和页表项未空也就是线性地址与物理地址的映射关系尚未建立或者已撤销。
然后需要注意的是在建立页面目录和页表项的同时我们不光在内存上分配页面目录项和页表项而且需要把虚存上的内容拷贝到内存页面上即一页4K但不一定是建立完全可以慢慢来嘛这也就是为什么那么多的进程可以同时运行在计算机上当他们所占的内存总和大于内存实际大小时操作系统同样能使其有条不紊的运行。这里举个例子想象一下比如要铺设从南昌到北京的火车轨道需要最短的轨道长度是多少答案不是两点线段最短而是只需要火车的长度就行因为我们可以拆东墙补西墙理论上只要我们铺轨道的速度足够快的话那么火车就好像一直行驶在轨道上了。
当用户进程申请扩展堆栈区间时由于申请的部分还没建立页面映射所以会产生一次缺页异常然后建立页面映射在内存分配页表而且分配一部分必须的页面空间。
进程三部曲创建执行消亡
linux操作系统每一个进程的创建都需要父进程复制出来的子进程有自己的task_struct进程控制块和系统空间堆栈但与父进程共享其他所有的资源。
实际上子进程通过fork(),clone()创建一个基于父进程一样的进程他们之间的区别在于子进程继承父进程资源的多少问题fork是完全继承而clone是有选择性的继承。
其中继承的资源有系统空间和用户空间但是子进程有自己的进程控制块。好了进程创建好了可以开始执行么显然和父进程一样的子进程有何用子进程必须得独立起来
这就到第二步子进程通过execve()加载自己的目标程序然后子进程和父进程分道扬镳走自己的路。
那么父进程呢父进程有三种选择
继续走自己的路与子进程分道扬镳如果子进程先于父进程“去世”则有内核给父进程发一个报丧信号若父进程没有收到那么子进程就成立僵尸进程需要init进程来处理。停下来进入睡眠等待子进程结束后唤醒父进程。父进程结束自己的生命此时子进程就成了孤儿进程全部都指向init作为自己的父进程子进程结束后统一给init进程发信号。
系统调用exit(),wait()
exit()系统调用是用来结束一个进程一个进程的结束那么就必须得释放它生前所占有的资源但是有部分资源是他自己不能主动释放的必须交给父进程来处理
还有两个关键问题 一个进程结束自己后他的子进程就成孤儿了它需要发送一个信号给它的所有子进程然后修改子进程的父进程指针统一指向init 一个进程结束自己后它必须的通知它的父进程最后给它收尸获得一个信号然后释放子进程结束后还占有的资源
注意
所谓的父进程有“生父”和“养父”之分一个进程在创建之初其生父和养父是一致的所以两个指针指向同一个父进程。
养父在运行时可以被短暂的改变比如。debug能让我们跟踪进程的执行情况被跟踪的进程同样成为子进程主动跟踪的进程则为其养父进程
如果一个进程在其子进程之前“去世”的话就要把它的子进程托付给某个进程。托付给谁呢如果当前进程是一个线程就托付给同一线程组中的下一个线程否则就只好托付给init进程 wait()调用可以说是进程同步的一个系统调用因为之前讲过父进程的情况又三种其中一种就是等待子进程结束那么wait()系统调用就是这么一个作用使自己进入睡眠并进行一次进程调用操作直到子进程结束后发送一个信号量唤醒父进程重新让父进程挂入活动进程队列参与进程调度。
内核中的互斥操作
如果一个进程进入了临界区A而又企图进入另外一个临界区B的话那就可能 因为进入不了那个临界区也就是得不到所需的资源而只好在B的队列中等待。那么所等待的资源又在谁的手里呢如果已经占有了那项资源的进程恰好也在A的队列中等待那就发生了“死锁”
互斥操作的两种机制就是信号量和锁。
信号量一般用于解决进程间互斥问题
锁则有很多种类其中自旋锁常用于多处理器之间互斥操作 信号量 简单的理解用信号量来表示某种资源一般资源数大多为1使用一次down一次直到为0后就不允许使用需要使用的进程都暂时进入睡眠状态等其他进程使用完up一次后又资源可以使用后再唤醒因此资源而睡眠的进程一次只能唤醒一个。
然后需要注意的一个问题就是当两个进程AB分别申请资源ab而进程A申请到a进程B申请到了b而彼此必须两者都拥有才能执行下次那么AB之间就陷入了死锁为了避免死锁也提出了很说算法其中最简单就是按序申请或者一次性能拿到所有资源的进程才允许分配如银行家算法。 自旋锁当不同的处理器访问临界资源时其中一个处理器允许访问那么另外一个处理器就必须等待那么这是处理器干嘛呢能不能做其他的事呢对于自旋锁而言另外一个处理器是什么都不做一直在循环做无用功看上去有那么点浪费但也没办法只能把处理器锁住。