精华内容
下载资源
问答
  • 多道程序的并发执行在
    千次阅读
    2020-10-29 21:42:20

    02进程学习之并发,时钟中断,单道程序设计和多道程序设计的区别

    1 并发的概念
    并发:一个时间段内可以运行多个程序。注意并不是同一时刻运行,即不是并行。

    2 时钟中断
    时钟中断:发送指令使当前占用CPU的进程停止并记录时间,好让其它进程可以执行。
    由于我们程序可以并发执行,所以每个程序都会争夺CPU,当我们需要切换另一个进程时,就是利用时钟中断来暂停它,记录本次时间等待其它进程执行完再回到被中断的那个时刻执行该进程。例如酷狗和微信的切换。

    3 单道程序设计
    单道程序设:“所有进程一个一个排对执行。若A阻塞,B只能等待,即使CPU处于空闲状态。所以已被淘汰。

    4 多道程序设计
    多道程序设计:内存中可以有多个进程轮流执行,不会阻塞,但需要硬件基础支撑。实际上就是并发的思想。

    5 四者的区别
    在不考虑单道程序设计下,多道程序设计是并发的实现,时钟中断是多道程序设计的前提。或者你可以理解为并发就是多道程序设计,毕竟这两个概念并不需要很严谨。

    更多相关内容
  • 下面从程序的顺序执行、程序的执行环境和程序并发执行几方面介绍多道程序设计模型。 一、程序的顺序执行 程序是一个时间上按严格次序前后相继的操作序列,这些操作是机器指令或高级语言编写的语句。人们习惯的...

    采用多道程序设计可以提高处理器的利用率。多道程序设计技术充分发挥了处理器与外围设备以及外围设备之间的并行工作能力,从而提高处理器和其他各种资源的利用率。下面从程序的顺序执行、程序的执行环境和程序的并发执行几方面介绍多道程序设计模型。

    一、程序的顺序执行

    程序是一个在时间上按严格次序前后相继的操作序列,这些操作是机器指令或高级语言编写的语句。人们习惯的传统程序设计方法是顺序程序设计,计算机也是以顺序方式工作的:处理器一次执行一条指令,对内存一次访问一个字节或字,对处部设备一次传送一个数据块。顺序处理也是人们习惯的思考方法,为了解决一个复杂的问题,人们把它分解成一些较为简单、易于分析的小问题,然后逐个解决。也可以把一个复杂的程序划分为若干个程序段,然后按照某种次序逐个执行这些程序段。

    我们把一个具有独立功能的程序独占处理器直到得到最终结果的过程称为程序的顺序执行。程序的顺序执行具有如下特点。

    1.顺序性

    程序所规定的动作在机器上严格地按顺序执行。每个动作的执行都以前一个动作的结束为前提条件,即程序和机器执行它的活动严格一一对应。

    2.封闭性

    程序运行后,其计算结果只取决于程序自身,程序执行得到的最终结果由给定的初始条件决定,不受外界因素的影响。程序所使用的资源(包括处理器、内存、文件等)是专有的,这些资源的状态(除了初始状态外)只有程序本身的动作才能改变。

    3.程序执行结果的确定性

    也称为程序执行结果与时间无关性。程序执行的结果与它的执行速度无关,即处理器在执行程序时,任意两个动作之间的停顿对程序的计算结果都不会产生影响。

    4.程序执行结果的可再现性

    如果程序在不同的时间执行,只要输入的初始条件相同,则无论何时重复执行该程序都会得到相同的结果。

    程序的顺序性和封闭性是一切顺序程序所应具有的特性,从这两个特性出发,不难引出程序执行时所具有的另外两个特性。顺序程序与时间无关的特性,可使程序的编制者不必去关心不属于他控制的那些细节(如操作系统的调度算法和外部设备操作的精确时间等);顺序程序执行结果的可再现性,则对程序检测和校正程序的错误带来了方便。

    二、程序的并发执行

    所谓程序并发执行,是指两个或两个以上程序在计算机系统中,同时处于已开始执行且尚未结束的状态。能够参与并发执行的程序称为并发程序。程序的并发执行,可以充分利用系统的资源,提高计算机的处理能力。但是,程序的并发执行产生了一些和程序顺序执行时不同的特性。程序的并发执行有如下特征。

    1.在执行期间并发程序相互制约

    资源的共享和竞争存在于多道程序的并发执行中,从而制约了各道程序的执行速度。由于本来并无逻辑关系的程序之间产生了相互制约的关系,而各个程序活动的工作状态与所处环境有密切关系,使并发程序的执行出现了“执行——暂停——执行”的活动现象。

    2.程序与计算不再一一对应

    在并发执行中,允许多个用户进程调用一个共享程序段,从而形成了多个“计算”。如在分时系统中,一个编译程序往往同时为几个用户提供编译服务,该编译程序便对应了几个“计算”。

    3.并发程序的执行结果不可再现

    并发程序执行结果与其执行的相对速度以及并发执行的多道程序之间的相互关系有关,导致并发程序的执行结果不可再现,即执行结果是不确定的。

    4.程序的并行执行与程序的并发执行

    多道程序的并发执行是指它们在宏观上,即在某一段时间周期内是同时进行的(这个时间周期,比处理器的指令处理周期要长得多,但是从操作人员的感觉来看,仍然时一个瞬间)。但从微观上看,除了多处理器系统外,在单处理器系统中,这些程序仍然是顺序执行的。

    程序的并行执行与程序的并发执行,这两者存在着差别。前者是指不论从宏观的时间周期上看,还是从微观上看,若干程序确实在同时运行;而程序的并发执行,如果在单处理器系统中,它们在宏观上是同时进行的,但在微观上,这些程序仍然是顺序执行的

    展开全文
  • 中国大学MOOC上学习操作系统 希望看视频可以直接点击 哈工大-操作系统课程MOOC CPU管理的直观想法 CPU通电后发生了什么? 以下面的指令为例 CPU发送一个地址50,即PC=50,也就是将50放在地址总线上 内存从50中...

    在中国大学MOOC上学习操作系统
    希望看视频可以直接点击 哈工大-操作系统课程MOOC

    CPU管理的直观想法

    CPU通电后发生了什么?

    以下面的指令为例
    在这里插入图片描述

    1. CPU发送一个地址50,即PC=50,也就是将50放在地址总线上
    2. 内存从50中取出指令,传回CPU的指令寄存器中(IR)
    3. CPU执行指令:将100地址中的值赋给ax寄存器
    4. PC++
    5. CPU执行指令:将101地址中的值赋给bx寄存器
    6. PC++
    7. CPU执行指令:ax + bx(一般直接将ax+bx放到ax中再取走)

    问题

    如果只是按照上面的使用方法,只是将CPU设置一个初始PC,就会出现下面的问题:I/O与计算的消耗差别。
    在这里插入图片描述
    两者甚至差了将近百万倍,I/O太耗费时间了,这是因为I/O需要对磁盘进行操作,磁盘是一个机械设备(使用磁头),内存是一个电子设备,两者工作速度不在一个量级上。
    这样就导致了CPU的利用率极低。

    能否在I/O时也使用CPU?

    跳过I/O然后直接计算直到计算完毕再使用I/O?
    错误,比如后面的指令依赖于这次I/O,那就读不到正确的数据,后面的程序就错了。
    举一个例子:
    比如烧水的时候(CPU在进行一个I/O任务),我们肯定不是干等,而是先做别的事情(切换任务),等到水烧好了自然会有滚水的声音(一个信号),这时我们再放下手中的事情(中断),去处理烧好的水。
    所以我们是在做多项任务,这就是多道程序设计。
    在这里插入图片描述
    多道程序、交替执行
    (DEV代表device)
    在这里插入图片描述
    这样理解:当A任务需要I/O时,把CPU控制权交给B,如果B也需要I/O,就等到A的I/O任务执行完成,这样不断交换资源控制权,就能提高CPU和I/O设备利用率。

    当一个CPU上交替执行多个程序:并发

    所以管理CPU就可以从并发入手。

    如何实现并发?

    在这里插入图片描述
    在这里插入图片描述

    显然不能光修改寄存器PC,还需要保存一下原来的一些状态以便后面回恢复状态,这就需要PCB(Process Control Block)。

    程序与进程

    在这里插入图片描述

    1. 运行的程序和静态的程序不一样
      PCB中保存的信息就是进程比程序多的那部分东西。
    2. 进程是进行(执行)中的程序
      进程有始有终,有走有停,需要记录。

    小结

    1. 操作系统需要使用CPU来执行任务
    2. 如果只执行一个任务,CPU的利用率太低,需要交替执行多个程序
    3. 多道程序使得我们必须使一种数据结构来(PCB)记录不同程序的信息,这就引出了进程的概念
    4. 进程和程序存在很大的不同

    多进程图像(Multiple Processes)

    多个进程使用CPU的图像

    根据前面的学习,我们可以回答下面的问题:

    1. 如何使用CPU?
      让程序执行起来
    2. 如何充分利用CPU?
      启动多个程序,交替执行

    启动了的程序就是进程,所以是多个进程推进:

    • 操作系统只需要把这些进程记录好、要按照合理的次序推进(分配资源、进行调度)

    多进程图像从启动开始到关机结束

    在这里插入图片描述
    每要解决一个问题就要启动一个进程,可见多进程极其其重要。
    在Windows中可以通过任务管理器查看一些相关的进程信息,这些信息就是存在PCB中的。

    多进程如何组织

    在这里插入图片描述

    1. 就绪队列(CPU调度)和磁盘等待队列(I/O)存储的都是PCB。
    2. 只有一个进程在被执行,因为只有一个CPU
    3. 多进程=PCB+状态+队列
      在这里插入图片描述

    多进程如何交替(切换)?

    在这里插入图片描述

    1. 启动磁盘读写
    2. 当前状态置为阻塞态
    3. 将该进程A放在一个阻塞队列(磁盘等待队列)上
    4. 切换
      1. 从就绪队列中取出队首的进程B(PCB),注意这个getNext和具体的调度策略有关
      2. 切换至此进程,同时要保存前边的进程A的状态以便后面恢复

    交替执行任务的三个部分:队列操作 + 调度 + 切换
    两种常见的调度方式(后面会讲更多):

    1. FIFO?
      1. 表面上非常公平
      2. 显然没有考虑不同种类进程的区别,类比急诊和门诊的关系
    2. Priority?
      优先级如何设定?是不是会导致某些进程饥饿?
    swtich_to

    在这里插入图片描述

    1. 前四行先保存当前CPU的状态
    2. 后四行将调度过来的进程状态赋给CPU
    3. 上面的代码实际应该写成汇编代码,因为涉及到对具体寄存器等硬件的操作。
    多个进程同时存在于内存会出现下面的问题

    在这里插入图片描述

    1. 当进程1和进程2同时操作100号地址时,比如上图进程1修改了100号地址,那么进程2再去使用的时候就会拿到错误的数据,极容易使进程2崩溃。
    2. 要解决上面的问题,就要限制进程1对100号地址的读写,这就引入了多进程的地址空间分离的思想,这也是内存管理的主要内容。
    3. 注意这里不能用前面DPL、CPL来限制访问,这是因为这两个数据结构是为了保护OS和用户之间的边界,不是用来做地址分离的。

    在这里插入图片描述
    在这里插入图片描述
    使用映射表的方式,将内存地址分离,限制进程可以读写的地址空间,做到进程地址空间的隔离。
    只有将内存管理好了,才能保证多个进程之间能够互不影响地执行,因此我们说多进程图像包含了进程管理和内存管理

    多进程如何合作?

    在这里插入图片描述

    打印机工作过程:

    1. 应用程序提交打印任务
    2. 打印任务被放进打印队列
    3. 打印队列从队列中取出任务
    4. 打印进程控制打印机打印

    出现了什么问题?
    当进程1和进程2都想放入7号地址,因为进程交替执行,可能导致两个进程都放入了一部分自己的数据,打印时就会出现问题。
    生产者-消费者实例:
    在这里插入图片描述
    实例解释:
    BUFFER_SIZE标记Buffer的最大值
    counter作为指示当前Buffer的已经使用的资源
    当Buffer为空,消费者进程进入死循环,不可以消费;假设没有这个死循环会读出来空值/错误值。
    当Buffer为满,生产者进程进入死循环,不可以生产;假设没有这个死循环,就会覆盖掉原来的正确数据。
    当Buffer非空非满时,生产者和消费者根据自己需要进行生产和消费。
    CPU会按照下面的代码进行运算:
    按照上面的思路,我们对生产者消费者案例已经做好了,可惜还是事与愿违:
    在这里插入图片描述
    当出现了右上角的那个执行序列,出现了错误结果。
    当生产者执行counter++操作中的一半,切到了消费者的counter - -,
    最后counter变成了4。我们期望的是生产者先将counter置为6后消费者再执行counter–,正确结果应该是5。
    如何解决?
    给counter上锁:
    即在某些特殊情况下,禁止进程的切换,变成“合理”的执行。
    在这里插入图片描述

    1. 生产者先关锁,然后执行counter++,执行到一半切换。
    2. 消费者检查counter锁,发现被锁住了,交出程序控制权
    3. 生产者继续执行完毕counter++,结束后开counter锁
    4. 消费者先关锁,执行counter–,执行完毕后,开锁

    小结:如何形成多进程图像?

    1. 读写PCB(这是OS中最重要的数据结构,贯穿始终)
    2. 要操作寄存器完成切换(进程、线程)
    3. 要写调度程序(CPU调度策略)
    4. 要有进程同步与合作(进程同步与信号量、临界区保护)
    5. 要有地址映射(内存管理)
    6. 解决死锁问题

    用户级线程(User Thread)

    多进程是操作系统的基本图像在这里插入图片描述

    在切换任务时那个映射表(也就是内存空间)我们应该如何切换?

    1. 切换:进程级切换
    2. 不切换:线程级切换

    在这里插入图片描述

    1. 进程 = 资源 + 指令执行序列,当我们只是将指令执行序列改变,而没有对资源切换时,就是线程的切换。我们可以将资源和指令执行区别开来,采用一个资源+多个指令执行序列的形式创造进程,这就是多线程技术。
    2. 线程优点:保留了并发的优势,并减少了进程切换的代价
    3. 线程切换的实质:映射表不变而PC指针变

    我们可以知道进程 = 资源 + 指令执行序列,那么进程切换 = 资源切换 + 指令序列切换,因此我们可以先搞明白指令执行序列如何切换,然后再搞明白进程是如何切换的,分而治之。
    (切换指令序列的过程实际上就是将PC设置的过程)

    多个执行序列 + 一个地址空间是否实用?有价值吗?

    网页浏览器
    1. 一个线程用来从服务器接收数据
    2. 一个线程用来显示文本
    3. 一个线程用来处理图片(如解压缩)
    4. 一个线程用来显示图片

    (题外话:作为前端程序员,我觉得这里老师讲的不是很准确,浏览器的线程分为GUI渲染线程-显示图片和文本、JavaScript引擎线程-解压缩、事件触发线程、定时触发线程、异步http请求线程-服务器数据)

    浏览器的线程需要功向资源吗?
    1. 接收的数据可能各个线程都要读写(CPU、内存)
    2. 所有的内容都要显示一个屏幕上(资源)

    显然这些线程需要共享这些资源,应当采用多线程,多线程是很有价值的。

    实现浏览器的思路

    在这里插入图片描述
    (注意这里的“多线程“只限于用户级线程,而不是内核级线程。)
    显然这里和核心就是如何实现Yield

    1. 能切换了就应该知道切换时需要是个什么样子
    2. Create实际上就是要制造出第一次切换时应该的样子。

    在这里插入图片描述
    当两个线程共用一个栈时:
    线程1:A、B
    线程2:C、D
    在这里插入图片描述
    (Yield函数是右侧红色的代码,用来找到下一条指令)
    (这里老师没有画错栈,是因为下面是高地址,就是栈顶)

    1. 执行A,要调用B,104代码压栈
    2. 执行B,要调用Yield,204代码压栈
    3. 执行Yield,找到下一个线程,即调用C
    4. 执行C,要调用D,304代码压栈
    5. 执行D,要调用Yield,404代码压栈
    6. 执行Yield,切回线程1:出栈404
    7. 没有我们想要的204出栈(左侧的栈),而是404出栈(共用的栈),程序错误了

    两个线程共用一个栈,造成了程序错误。
    因此我们必须使用两个线程+两个栈来处理:
    Yield切换时也必须要切换栈。
    如何保存线程的状态呢?TCB(Thread Control Block)
    在这里插入图片描述
    (红色长箭头表示CPU在执行哪一个线程)
    线程1要使用esp=1000的栈,线程2要使用esp=2000的栈,因此我们需要在TCB中保存两个栈的esp
    (对于栈的描述要使用栈帧,栈帧保存着esp和ebp,分别为栈顶指针和栈底指针,esp:extended stack pointer,ebp:extended base pointer)
    使用两个栈时:

    1. 执行A,调用B,104压入esp=1000栈中
    2. 执行B,调用Yield,204压入esp=1000栈中,
    3. 执行Yield,并切换至esp=2000栈,切换至线程2,调用D
    4. 执行D,调用Yield,404压入esp=2000栈中
    5. 执行Yield,并切换至esp=1000栈,切换到线程1,esp=1000出栈204,程序正常。
    6. 执行204,结束后检测到函数返回,esp=1000出栈104
    7. 执行104,结束后检测到函数返回,并且esp=1000栈空,自动调用Yield,切换至线程2,esp=2000
    8. 后边就很简单了,不再分析。

    为什么说jmp语句可以不要:
    因为Yield调用结束,上个线程正好是我们为了保存状态压栈了跳回的PC指针位置,当Yield函数调用结束后204立刻会出栈,所以不需要再jmp,这是多余的。

    两个线程的样子

    1. 两个TCB
    2. 两个栈
    3. 需要切换的PC在自己的栈里面了

    在这里插入图片描述

    对浏览器的简单实现

    在这里插入图片描述
    几乎所有的浏览器都会按照上面的架构来实现“用户级多线程”

    为什么说是用户级线程——Yield是用户程序

    在这里插入图片描述
    按照架构图,可以发现无论我们定义的Yield如何使“线程”切换,都只是在用户态来做文章,不会进入到内核态,因此说是用户级线程。
    用户级线程的问题:

    1. GetData
      1. 连接URL发起请求
      2. 等待网卡I/O,必须要进入内核的进程调度
      3. 网卡阻塞了进程1,造成CPU空等
      4. 还是阻塞了整个进程,导致Show没法继续进行,也就是说一旦内核阻塞了进程,这种线程的并发就没有了。
    内核级线程

    在这里插入图片描述
    当我们使用了内核级线程以后,会使用系统调用级(不再是Yield,而是系统的Schedule)的线程I/O来帮助我们处理网络请求部分,CPU又利用起来了。
    (题外话:其实从名字中也可以看出来,Yield代表的是“让步、放弃、暂停”,而Schedule才是真正意义上的“调度”)
    可见:内核级线程的并发性一定优于用户级线程

    内核级线程(Kernel Threads)

    为什么没有听说过用户级进程?
    因为进程需要分配资源,而对于用户来讲,资源是不可见的,简单来讲就是用户态无法访问资源,只能依靠操作系统进行调度,所以不可能有用户级进程

    开始在这里插入图片描述

    多CPU与多核CPU(多核用的比较多)
    区别(看架构图):

    1. 多处理器有自己的缓存(Cache)和MMU(Memory Management Unit,用于管理内存)
    2. 多核CPU的Cache和MMU是共享的

    多核只有在多线程的辅助下才能发挥能力。
    多处理器/多核心的产生,有了一个新概念,并行:多个程序同时(注意不是交替)执行。

    内核级线程有什么不同?

    在这里插入图片描述

    1. ThreadCreate是系统调用,内核管理TCB,内核负责切换线程。
    2. 如何让切换成型? - 内核栈
      用户栈依然需要,因为执行的代码仍在用户态,还是需要进行函数调用
    3. 一个栈到一套栈,两个栈到两套栈
    4. TCB关联内核栈,用户如何找到这个栈呢?
      当内核栈切换的时候,用户栈也必须跟着切换。
    用户栈和内核栈之间的关联

    中断是进入内核态的唯一方式。
    (CS:Code Segment Register)
    在这里插入图片描述

    1. 一旦使用了INT,操作系统就会自动启用内核栈,并通过指针整合用户栈,两个栈成一套栈,并且包含了源PC、源CS、EFLAGS。
    2. 一旦使用了IRET,操作系统自动退回到用户态,栈自动转为原来的用户栈。

    实例

    在这里插入图片描述

    1. 执行A,调用B,压栈104
    2. 执行B,调用read(),压栈204
    3. 执行read,调用int 0x80。
    4. 执行int 0x80,立刻中断,进入内核态,ss指向栈底,sp指向栈顶,PC指向304,CS指向段基址(也就是线程初始的位置100,所以指向了A)
    5. 执行1000,调用sys_read()
      在这里插入图片描述
    6. 执行sys_read(),启动磁盘读,并阻塞自己,找出下一个线程并切换线程(内核级的切换),然后调用swtich_to
      switch_to:
      cur:当前的TCB
      next:下一个TCB
      函数将当前内核栈中的esp保存到cur,并将内核栈的esp指向next中的esp。
    7. 执行switch_to,通过TCB找到内核栈指针,然后通过ret切到某个内核程序,最后iret再根据CS、PC切回用户态。

    上面的那些问号

    在这里插入图片描述
    在这里插入图片描述

    1. ??:PC和CS,指向了返回用户态时的PC和CS,也就是上面进入内核态的时候存的,也还是中断(就是用户态的时候)执行的位置。
    2. ???:sys_read的某个地方
    3. ???:一段能完成第二级返回的代码,一定要包含一段iret代码。

    内核级线程swtich_to的五段论

    在这里插入图片描述

    1. 中断入口-进入切换,启动中断(int 0x80),此时刚进入内核态,需要保存一些用户态信息,并建立内核栈和用户栈关联。
    2. 中断处理-引发切换,可能会引起阻塞(sys read)
    3. schedule,找到TCB,准备内核栈的切换
    4. swtich_to:内核栈切换,ret,第一级切换
    5. 中断出口:第二级切换,iret返回用户态,用户栈切换,自此一套栈切换成功,内核级线程切换完成。

    如果是需要切换进程,就有有右上角的那段代码,即,将地址映射表切换。

    如何实现TreadCreate

    在这里插入图片描述
    只要保证有用户栈、内核栈、TCB,再准备好一段包含iret的代码就算做好了切换的准备,ThreadCreate按照这些数据结构创建即可。

    1. 创建一个TCP
    2. 申请一段内存作为内核栈,把内核栈(krlstack,kernel stack)内容初始化
    3. 传入用户栈
    4. 填写两个栈
    5. 填写状态
    6. 将TCB装入线程等待队列

    用户级线程、内核级线程的对比

    在这里插入图片描述
    多对一、一对一、多对多的三种模型。

    1. 利用多核:显然多对一模型只能用一个核,多核利用性最差
    2. 并发度:多对一模型在内核级依然有阻塞的现象,并发性不强
    3. 代价:多对一模型只需要一个内核即可完成,一对一模型有几个内核就要用几个内核。
    4. 内核改动:多对一模型压根不需要改内核
    5. 用户灵活性:一对一模型没有给用户操作的空间。多对一模型和多对多模型想起几个线程就起几个线程。

    内核级线程的代码实现

    课程链接

    内核级线程的两套栈,核心就是内核栈

    内核级线程切换实现的难度就在内核栈的切换
    对于用户来讲,上面的switch_to五段论是无感知的。
    在这里插入图片描述

    从fork理解内核级线程切换

    在这里插入图片描述

    1. 对于用户栈main来说,ret=exit就是让程序回到A结束的后面,也就是B
    2. fork会变成下面的那段代码
      1. 将系统调用(__NR_fork)传给%eax
      2. 中断,int 0x80,一旦执行INT指令以后,CPU会找到内核栈,连接上用户栈,并将PC和CS压进栈。
      3. 将PC+1放到res,切换回来时,ret会找到res作为PC指向。
        此时由用户态进入内核态

    五段论中的中断入口和出口

    在这里插入图片描述
    中断入口:
    在这里插入图片描述

    1. 执行_system_call,将用户态的一堆东西记录下来,为了以后回来还能接着执行。然后执行sys_fork,这就有可能会引起内核级线程的切换。
    2. 读取PCB(_current)的state,比较是否为0(就绪状态,非0就阻塞了,比如write、read就会阻塞),jne(如果不是)就调用调度算法。

    schedule(五段论中间三段,用C语言函数实现,这节课不关心这个):
    在这里插入图片描述
    schedule完成内核栈的切换,并把指令序列也切换

    中断出口:
    在这里插入图片描述

    1. 判断时间片是否为0,je(如果是)继续调用调度算法
    2. ret_from_sys_call,从系统中断中返回。

    reschedule(在最上边的那个大图):

    1. 先把ret_from_sys_call压进来
    2. 转去执行schedule,当schedule结束后,弹出ret_from_sys_call,并调用。

    swtich_to(这里没有看懂)

    假设调度算法已经执行完,看一下swtich_to
    Linux 0.11中使用了TSS(Task State Segment,任务状态段)进行切换,效率不如krlstack那种切换,即内核栈的切换。
    在这里插入图片描述
    类似前面CS通过GDT寻找指令的逻辑,可以通过TR(类比CS,是一个段寄存器)来找到当前进程的TSS。
    TSS包含了所有的寄存器内容,比如PC、eax。
    使用TSS类似快照,就是先将当前现场记录一下,然后选择一个新的现场来继续执行。长跳转至TSS段选择符造成CPU执行任务切换操作。
    三句最重要的代码:

    1. int 0x80,开中断,进入内核态
    2. switch_to 中的那句ljmp(长跳转),调度
    3. iret,返回用户态,关中断

    ThreadCreate

    在这里插入图片描述

    1. 调用_copy_process,这是fork的作用,将父进程的信息copy,一堆在内核栈的东西都被复制过来了,创建一个近乎一样的内核栈。
      (_copy_process函数取值,是从栈顶开始取,也就是??4部分赋给nr,依次赋给copy_process)
      eip是int 0x80后面的那条指令。
    2. 创建栈
      在这里插入图片描述
      (一定不要使用malloc,这是用户态的代码)
      创建栈
      1. 使用get_free_page获取一段内存(在初始化mem_map时,将内存按照4kB分页,这里就是申请了4kB的内存)作为PCB
      2. 创建栈(包括内核栈和用户栈)并填写
      3. 关联栈和PCB
      4. 实际上那一页内存就包含了PCB和内核栈
    3. 执行前准备
      在这里插入图片描述

    小结

    1. fork执行,造成父进程阻塞
    2. 系统调用schedule
    3. schedule内会调用switch_to,切换到子进程
    4. 子进程将TSS内容交给CPU,eip指向INT 0x80指令的后一条指令。

    在这里插入图片描述

    展开全文
  • 操作系统原理,多道程序设计,并发环境与并发任务,进程定义,进程控制块PCB,PCB维护的进程数据 一、多道程序设计: 1、允许多个程序同时进入内存运行,目的是为了提高系统效率。 2、每个程序有自己的程序计时器,...

    操作系统原理,多道程序设计,并发环境与并发任务,进程定义,进程控制块PCB,PCB维护的进程数据

    一、多道程序设计:
    1、允许多个程序同时进入内存运行,目的是为了提高系统效率。
    2、每个程序有自己的程序计时器,物理上只有一个计时器,每个程序在占用CPU时,会将自己的计时器里的内容推送到物理计时器中,通过这种操作,使得多个应用程序可以同时在内存中执行。
    3、宏观上:多个应用程序在并发进行
    4、微观上:单个CPU任然在串行处理任务。

    二、并发环境:
    1、一段时间间隔内,单个处理器上有两个或两个以上的程序同时处于开始运行但尚未结束的状态并且次序不是事先确定的。
    2、并发环境下执行的程序就是并发程序。

    在这里插入图片描述

    三、进程process的定义:
    进程是具有独立功能的程序关于某个数据集合上的一次运行活动,是系统进行资源分配和调度的独立单位,又叫任务。

    注意:
    1、进程是程序的一次执行,
    2、是正在运行的程序的抽象,
    3、是对CPU的抽象,可以将一个物理CPU变换为多个虚拟的CPU
    4、系统资源以进程为单位分配,如内存,文件,每个进程拥有独立的地址空间
    5、操作系统将物理CPU调度给需要的进程,就是将CPU的控制权交给该进程

    四、进程控制块PCB:
    1、PCB,process control block,又称进程描述符,进程属性。
    2、操作系统用于管理进程的一个专门的数据结构,记录进程的各种属性,描述进程的动态变化过程。
    3、CPB是操作系统感知进程才能在的唯一标志,进程与PCB是一一对应的。
    4、所有进程的PCB集合就是进程表,进程表的大小是固定,其最大值就是操作系统的并发度。

    五、PCB维护的进程数据:
    1、通用信息
    a、进程标识符PID,唯一,整数
    b、进程名,通常基于可执行文件名,不唯一
    c、用户标识符uid
    d、进程组关系,父进程,兄弟进程等关系

    2、进程控制信息:
    a、当前状态
    b、优先级priority
    c、代码执行入口地址
    d、保存的磁盘地址
    e、运行统计信息(执行事件,页面调度)
    f、进程间同步和通信
    g、进程的队列指针
    h、进程的消息队列指针

    3、进程拥有的资源和使用情况:
    a、虚拟地址空间的状况
    b、打开的文件描述符

    4、CPU现场信息,进程不运行时保存在PCB中的进程硬件信息:
    a、寄存器值(通用寄存器,程序计数器PC,程序状态字PSW,栈指针)
    b、指向该进程页表的指针

    展开全文
  • 程序并发执行的特征

    千次阅读 2020-10-13 22:14:34
    1:间断性:程序在并发执行的...2:失去封闭性:当系统中有并发执行程序时,各个资源是他们所共享的,这些资源的状态也由这些程序所改变,所以摸一个程序运行环境会受到其他程序的影响。 3:不可再生性 ...
  • 多道程序设计是什么意思?

    千次阅读 2021-07-28 04:14:20
    多道程序技术运行的特征:多道、宏观上并行、微观上串行。多道程序设计必须有硬件基础作为保证。所谓多道程序设计指的是允许多个程序同时进入一个计算机系统的主存储器并启动进行计算的方法。也就是说,计算机内存中...
  • 题目内容:大贤者福尔的计算机方面的研究也取得了极大的成绩,他的研究主要集中并行计算方面,通过锁机制保障程序的并行执行。为此,他设计了一个非常简单的原型系统,系统中程序最多不超过100条语句,分为以下...
  • boost实现的多并发处理服务器,来自网络高手,简单修改,能windows 10成功运行
  • 程序并发执行

    千次阅读 2020-03-07 11:16:57
    今天学习了程序并发执行并发执行,指两个或两个以上程序在计算机系统中,同时处于已开始执行且尚未结束的状态。能够参与并发执行程序称为并发程序。并发程序的执行和程序顺序执行的特征不同。 并发执行的特征...
  • 技术:多道程序技术。 并发的是程序程序。 特点:系统资源利用率提高;具备间断性,不能连续的执行,是因为等待其他段运行的结果或者占用的资源;失去封闭性,因为资源共享和没有顺序性的原因,共享资源被先后...
  • 程序顺序执行和并发执行时的特征

    千次阅读 2022-03-18 08:20:50
    顺序执行时 1.顺序性:严格的按照顺序执行 ...2.失去封闭性:并发执行程序共享计算机资源,这些资源的状态由这些程序改变 3.不可再现性:并发执行程序执行的顺序不同可能有不同的执行结果 ...
  • 编写一个程序,完成个线程的创建,使得所创建的线程处理机上并发执行。通过本实验,学习Win32程序中利用操作系统提供的API创建线程,并通过所创建线程的运行情况来获得关于线程并发的感性认识,以及加深对...
  • 概念上来说,进程并发运行多个独立的程序,优势在于并发处理的任务都由操作系统管理,不足之处在于程序与各进程之间的通信和数据共享不方便;线程并发则由程序员管理并发处理的任务,这种并发方式可以方便地...
  • 设计一种Qt Creator下的并发性能分析方案,通过实时监控程序并发事件,采集程序运行过程中的并发性能数据,分析程序并发性能瓶颈和死锁原因,并以插件形式进行视图数据显示.通过实验表明,该并发性能分析方案可以...
  • 多道程序系统

    千次阅读 2017-07-10 20:10:36
    多道程序设计技术是计算机内存中同时存放几道相互独立的程序,使它们管理程序控制下,相互穿插运行,两个或两个以上程序在计算机系统中同处于开始到结束之间的状态, 这些程序共享计算机系统资源。与之相对应的是...
  • 文章目录程序vs进程并发与并行进程的状态进程何时离开CPU进程的状态转化图 程序vs进程 ❓什么是程序程序的英文解释: 中文翻译:程序是一个被动的实体,比如一个文件包含了一系列的指令存在磁盘中(通常叫为可...
  • 让计算机程序并发运行是一个经常被讨论的话题,今天我想讨论一下Python下的各种并发方式。
  • shell脚本实现程序并发执行

    千次阅读 2021-03-14 10:25:03
    shell脚本实现程序并发执行 循环实现并发程序: 并发的实现原理是将进程放到后台运行,从而不影响当前shell的运行shell脚本中有&符号可以实现这个操作。 # !/usr/bin/bash echo "hello multiprocess" for ...
  • 随着实际应用对并发软件需求的不断增加,并发程序的应用越来越广,程序切片的研究不再仅仅局限于顺序程序,并发程序切片的研究也越来越。但是由于并发程序执行的不确定性,并发程序切片的研究还有许多问题有待解决。...
  • 不管是并行与并发用户看起来都是‘同时’运行的,他们都只是一个任务而已,正在干活的是cpu,而一个cpu只能执行一个任务。 并行就相当于有好多台设备,可以同时供好多人使用。 而并发就相当于只有一台设备,供几...
  • 内存中执行。(程序运行起来之后,产生一个进程)。 那么我们可以形象的将程序比作一个剧本,这个剧本就是一张一张的纸组成的,那么就是进程就要演的戏,一出戏上面包括舞台、演员、灯光、道具等等。同一...
  • 程序并发执行时的特征

    千次阅读 2020-02-13 16:25:28
    间断性。程序在并发执行时,由于他们共享资源等原因导致彼此间形成了相互制约的关系。 失去封闭性。 不可再现性。程序在并发执行时由于不知道哪个程序会被优先执行导致处理结果可能出现不一致。 ...
  • 1、模拟公司会计与出纳行为,会记收账并往公司账户存钱,出纳从公司同一账户取钱用于开支,假定公司只有一个出纳和一个会计。编程实现会计与出纳行为。 ... 3、解决2中的问题。 ...用线程及条件变量机制编程实现这一问题。
  • 四、 程序并发执行

    千次阅读 2020-05-23 16:59:52
    间断性:程序在并发执行时,由于它们共享系统资源,以及为完成同一项任务而相互合作,致使这些并发执行程序之间形成了相互制约的关系。(当图中C1已经数据处理完毕时,I2还没有输入那么C2就得进入暂停,当使C2...
  • 本帅博主和伙伴们正在学习,遇上一个较为冗长的程序例子,又必须打出来,但是又不想占用太时间。像我这样,既想要敲出这个程序,又不想占用自己太时间,该怎么办呢?...这段时间本帅博主一直JVM和并发...
  • windows系统下,鼠标双击某后缀名.exe软件时,通过后台查看,运行的.exe即为可执行程序;而Linux系统下,这里我实验的是Ubuntu下,通过终端ls -la查看可执行文件获取该文献是都具有x权限,即判断是否为可执行...
  • 设计有5个进程并发执行的模拟调度程序,每个程序由一个PCB表示。  模拟调度程序可任选两种调度算法之一实现(有能力的同学可同时实现两个调度算法)。  程序执行中应能屏幕上显示出各进程的状态变化,以便于观察...
  • python并发执行进程

    千次阅读 2021-01-29 18:26:00
    进程顾名思义程序启动的时候运行多个进程,每个进程启动一条线程进行程序处理。 没启动一个进程就要单独划分一块内存资源。就像工厂的厂房。为了提高效率每添加一条生产线就要单独再盖一个厂房。每个厂房相互是...
  • 运行任务:代理池(Python爬虫代理IP池(proxy pool)),url:https://github.com/jhao104/proxy_pool 代理池启动方式: 如上所述:启动代理池时发现需要同时启动两个py文件,但是每次去找到两个不再同一个位置的...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 803,989
精华内容 321,595
热门标签
关键字:

多道程序的并发执行在