精华内容
下载资源
问答
  • 所以说在正式环境打包压缩代码速度非常慢,ParallelUglifyPlugin 插件会开启多个子进程,把对多个文件压缩工作分别给多个子进程去完成(workerCount:开启几个子进程并发的执行压缩。默认是当前运行电脑 CPU ...

    step1:应用场景
    webpack默认提供了UglifyJS插件来压缩JS代码,但是它使用的是单线程压缩代码,所以说在正式环境打包压缩代码速度非常慢,ParallelUglifyPlugin 插件会开启多个子进程,把对多个文件压缩的工作分别给多个子进程去完成(workerCount:开启几个子进程去并发的执行压缩。默认是当前运行电脑的 CPU 核数减去1。)
    step2:安装 webpack-parallel-uglify-plugin 插件

    npm i -D webpack-parallel-uglify-plugin
    

    然后在webpack.prod.config.js 文件中
    引用

    var ParallelUglifyPlugin = require('webpack-parallel-uglify-plugin')
    

    new webpack.optimize.UglifyJsPlugin({
      compress: {
        warnings: false,
        drop_console: true,
        pure_funcs: ['console.log']
      },
      sourceMap: false,
      uglifyJS:{
        output: {
          beautify: false,
          comments: false
        }
      }
    }),
    

    替换成

    new ParallelUglifyPlugin({
      cacheDir: '.cache/',
      uglifyJS:{
        output: {
          comments: false
        },
        warnings: false,
        compress: {
          drop_debugger: true,
          drop_console: true
        }
      }
    }),
    

    试一下,打包时间将会缩短至少一倍!

    展开全文
  • 理解并发进程

    2019-04-18 18:55:00
    顺序程序设计具有四种特性:(1)执行的顺序性(2)环境的封闭性(3)结果的确定性(4)过程的可再现性。程序顺序执行与其速度无关,即程序的最终输出仅与初始输入数据有关,而与时间无关。 二、并发程序设计: ...

    一、顺序程序设计:

    顺序程序设计具有四种特性:(1)执行的顺序性(2)环境的封闭性(3)结果的确定性(4)过程的可再现性。程序顺序执行与其速度无关,即程序的最终输出仅与初始输入数据有关,而与时间无关。

    二、并发程序设计:

    并发进程的特性:并发进程可能是无关的,也可能是交互的。无关的并发进程是指它们分别在不同的变量集合上的操作,一个进程的执行与其他并发进程的进展无关,即一个进程不会改变另一个与其并发执行的进程的变量。然而,交互的并发进程共享某些变量,一个进程的执行可能会影响其他进程的执行结果,交互的并发进程之间具有制约关系。因此,进程的交互必须是有控制的,否则会出现不正确的计算结果。

    例子:

    并发程序设计:

    在一个单处理器系统中,从磁盘读入数据经加工后打印输出,不采用并发程序设计时,解决这个问题的程序是循环地执行读入一批数据,然后,加工打印输出。执行这个程序时,磁盘机、处理器和打印机顺序执行输入、加工和输出操作。虽然计算机的外围设备和处理器可以并行操作,但执行上述程序时它们只能串行工作。如果采用并发程序设计,解决上述问题的程序由以下两个进程组成。①读盘进程:循环地执行读入一批数据,加工后送入输出缓冲区;②打印进程:循环地执行从缓冲区取出数据打印输出。在打印进程执行打印输出时只需要打印机,而不需要磁盘机和处理器。因此,在打印进程启动打印机后,在打印机输出的过程中可以启动读盘进程输入和加工数据。执行这个程序时,处理器、磁盘机和打印机并行工作,能缩短程序执行的时间,提高计算机系统的效率。

    顺序程序设计:

    a = 3,b = 5,现交换a,b的值,这个问题就好像交换两个杯子水,这当然要用到第三个杯子,假如第三个杯子是c,那么正确的程序为: c = a; a = b; b = c; 执行结果是a = 5,b = c = 3如果改变其顺序,写成:a = b; c = a; b = c; 则执行结果就变成a = b = c = 5,不能达到预期的目的,初学者最容易犯这种错误。 顺序结构可以独立使用构成一个简单的完整程序,常见的输入、计算,输出三部曲的程序就是顺序结构,例如计算圆的面积,其程序的语句顺序就是输入圆的半径r,计算s = 3.14159*r*r,输出圆的面积s。不过大多数情况下顺序结构都是作为程序的一部分,与其它结构一起构成一个复杂的程序,例如分支结构中的复合语句、循环结构中的循环体等。

    转载于:https://www.cnblogs.com/qx77/p/10731593.html

    展开全文
  • 进程进程简单定义是指装载到内存指令集并且正在由cpu执行其中每一条指令这个程序叫做进程进程控制块 process control block 简称PCB,主要包含了标识符,状态,优先级,程序计数器,内存指针,上下文数据,...

    128058617f2644617ea2f3d5634f2510.png

    进程

    进程简单的定义是指装载到内存的指令集并且正在由cpu执行其中的每一条指令的这个程序叫做进程。

    进程控制块 process control block 简称PCB,主要包含了标识符,状态,优先级,程序计数器,内存指针,上下文数据,I/O状态信息以及所谓记账信息。

    进程有一个五状态模型,分别为新建,就绪,运行,退出,阻塞状态,由于I/O比cpu处理速度慢,所以有时候所以可以需要挂起状态表示进程没有占有内存空间,可以细化为阻塞/挂起状态,就绪/挂起状态,挂起状态跟阻塞状态是不一样,阻塞状态是等待某个事件的返回。

    这一章还有一个上下文切换,主要是指用来记录当前进程或者线程在被中断和重新执行的时候的所有当前状态,包括用户空间的资源的状态和内核空间的状态。

    线程

    线程简单的定义就是线程是进程中一个执行流程。

    进程和线程的区别:

    线程与进程最大的区别在于:线程是调度的基本单位,而进程则是资源拥有的基本单位。

    线程共用进程的所分配到的内存等计算资源,但有独立的堆栈,寄存器。

    线程主要分为三类,用户级线程,内核级线程,轻量级进程,这三者主要区别就是用户级线程就是应用自身产生线程来执行,例如jvm。内核级线程就是有系统内核产生线程来执行,例如linux,windows本身。轻量级进程是内核支持的用户线程,一个进程可有一个或多个 LWP,每个 LWP 是跟内核线程一对一映射的,也就是 LWP 都是由一个内核线程支持。

    另外,LWP 只能由内核管理并像普通进程一样被调度,Linux 内核是支持 LWP 的典型例子。

    并发

    如之前所说,由于I/O比cpu处理速度慢,所以导致并发的出现,并发和并行的区别主要是,并行是多个应用或程序同时执行,并发则是多个应用或程序在同一计算机资源轮流交替进行。所以并发会产生进程之间的资源抢占问题,主要有三类,互斥,饥饿和死锁。

    死锁 简单来说,两个及以上程序互相占有彼此下一步运行需要的资源,具体产生需要四个(有一个条件不成立,则不会产生死锁)互斥条件:

    一个资源一次只能被一个进程使用请求与保持条件

    一个进程因请求资源而阻塞时,对已获得资源保持不放不剥夺条件

    进程获得的资源,在未完全使用完之前,不能强行剥夺循环等待条件

    若干进程之间形成一种头尾相接的环形等待资源关系

    解决死锁的基本方法如下:

    预防死锁、避免死锁、检测死锁、解除死锁

    银行家算法 简单来说判断当前剩余的资源能否满足当前进程申请的资源,能则分配不能则推迟分配,同时还有几个其他的原则,一是计算资源固定,二是知道所有进程需要消耗的资源,三是所有进程之间无先后执行相关性,四是进程在占用的资源时候不能退出。

    饥饿 两个程序互相轮流占用第三方下一步需要运行的资源。

    常见的并发解决机制:信号量,二元信号量,互斥量,条件变量,管程,信箱/信息,自旋锁,事件标志。这里主要介绍管程(Monitor),与golang的channel类似(这里个人猜想golang的channel就是基于管程设计出来的)

    线程同步的方法互斥锁,信号量,条件变量

    linux 内核并发机制主要四种,分别是原子操作,自旋锁,信号量,屏障。

    原子操作是指将某些指令设计为不能被打断的运行指令。

    自旋锁是指指令会一直重试去获取直到获取到该锁。

    信号量是指设计一个数据结构用来标记资源的占用情况。

    屏障就是保证该原指令不会被中断。

    调度

    主要有以下几个算法,非抢占式的顺序处理(First Come First Severd, FCFS)算法,高响应比优先 (Highest Response Ratio Next, HRRN)调度算法,最短作业优先(Shortest Job First, SJF)调度算法,时间片轮转(Round Robin, RR)调度算法以及最高优先级(Highest Priority First,HPF)调度算法,调度多级反馈队列(Multilevel Feedback Queue)调度算法。

    参考资料

    进程和线程基础知识全家桶,30 张图一套带走

    Stallings, W., n.d. Operating Systems: Internals And Design Principles, Global Edition. 7th ed.

    展开全文
  • OS Review3 并发进程

    2020-07-03 15:41:58
    并发进程 顺序程序设计 顺序性不但指一个程序模块内部,也指两个程序模块之间 内部顺序性 一个程序在处理器上的执行是严格按序,只有前一个操作结束后,才能开始后继操作 外部顺序性 一个计算任务需要若干不同...

    并发进程

    顺序程序设计

    顺序性不但指一个程序模块内部,也指两个程序模块之间

    • 内部顺序性
      一个程序在处理器上的执行是严格按序的,只有前一个操作结束后,才能开始后继操作
    • 外部顺序性
      一个计算任务需要若干不同程序完成,这些程序也按照调用次序严格有序执行

    顺序程序设计特点

    • 程序执行的顺序性
      在处理器上是严格按序执行的
    • 程序环境的封闭性
      运行程序独占全机资源,资源状态只能由此程序本身决定和改变,也不受外界因素影响
    • 执行结果的确定性
      执行过程中允许出现中断,但中断不会对程序最终结果产生影响,程序执行结果与执行速度无关
    • 计算过程的可再现性
      重复执行程序会获得相同的执行过程和计算结果
    • 并发打破了程序执行的顺序性

    进程的并发性

    • 进程执行的并发性
      一组进程的执行在时间上是重叠的,即多个程序处于都已开始执行但都未执行完成状态
    • 可交替进行
      从宏观上看,并发性反映一个时间段中几个进程都在同一处理器上,处于运行还未运行结束状态
      从微观上看,任一时刻仅有一个进程在处理器上运行

    并发的本质

    一个处理器在几个进程之间的多路复用,是对有限物理资源强制行使多用户共享,消除计算机部件之间的互等现象,以提高系统资源利用率

    并发程序设计 (concurrent programming)

    • 一个程序被设计成可与其他程序并发执行的程序设计方法

    并发程序特点

    • 对于单处理器系统,可让处理器和各I/O设备同时工作,发挥硬部件的并行能力
    • 对于多处理器系统,可让各进程在不同处理器上物理地并行,加快计算速度
      简化程序设计任务

    并发进程的分类

    • 无关的并发进程
      并发进程分别在不同的变量集合上操作,一个进程的执行与其他并发进程的进展无关
      一个进程不会改变另一个与其并发执行的进程的变量
    • 交互的并发进程
      并发进程共享某些变量,一个进程的执行可能会影响其他进程的执行结果
      交互的并发进程之间具有制约关系,进程的交互必须是有控制的,否则会出现不正确的计算结果

    Bernstein条件

    并发进程的无关性是进程的执行与时间无关的一个充分条件

    只要要满足Bernstein条件,并发执行的程序就可以保持封闭性和可再现性

    与时间有关的错误

    对于一组交往的并发进程,执行的相对速度无法相互控制,各种与时间有关的错误就可能出现,甚至无法再现

    • 结果不唯一:飞机售票问题
    • 永远等待:内存资源管理问题

    进程的交互

    竞争关系

    • 原本不存在逻辑关系的多个进程因共享一套计算机系统中的资源而产生交互和制约关系
    • 是一种间接制约关系,又称互斥关系(mutual exclusion)
    • 进程互斥指若干个进程因相互争夺独占型资源时所产生的竞争制约关系
    • 竞争资源的独立进程之间并不交换信息,一个进程的执行可能影响到竞争资源的其他进程

    资源竞争的两个控制问题

    • 死锁(Deadlock)问题:因争夺资源陷入永远等待的状态
    • 饥饿(Starvation) 问题:由于其他进程总是优先于它,而被调度程序无限期地拖延而不能被执行

    解决途径:分配策略

    • 最简单策略解决策略:FCFS资源分配策略

    协作关系

    • 是一种直接制约关系
    • 进程为完成同一任务需要分工协作,由于每个进程都独立地以不可预知的速度推进,在执行的先后次序上就要有约束,需要相互协作的进程在某些关键点上协调各自的工作

    进程同步(synchronization)指两个以上进程基于某个条件来协调它们的活动

    • 一个进程的执行依赖于协作进程的消息或信号
    • 当一个进程没有得到来自于协作进程的消息或信号时需等待,直到消息或信号到达才被唤醒

    进程互斥关系是一种特殊的进程同步关系,即逐次使用互斥共享资源,是对进程使用资源次序上的一种协调

    临界区管理

    临界区(critical section)

    • 并发进程中与共享变量有关的程序段

    临界资源

    • 共享变量代表的资源,即一次仅能供一个进程使用的资源

    竞争条件(race condition)

    • 当多个并发进程访问临界资源时,结果依赖于它们执行的相对速度,便称出现了竞争条件

    与同一变量有关的临界区分散在各进程的程序段中,而各进程的执行速度不可预知

    • 如果保证进程在临界区执行时,不让另一个进程进入临界区,即各进程对共享变量的访问是互斥的,就不会造成与时间有关的错误

    互斥与临界区

    临界区调度原则(Dijkstra)

    • 一次至多一个进程能够进入临界区内执行
    • 如果已有进程在临界区,其他试图进入的进程应等待
    • 进入临界区内的进程应在有限时间内退出,以便让等待进程中的一个进入

    总结

    • 互斥使用、有空让进
    • 忙则等待、有限等待
    • 择一而入、算法可行

    实现临界区管理的几种尝试

    软件方法实现临界区管理(并发进程在单处理器或共享内存的多处理器计算机系统执行)

    硬件假设

    • 通常假设具有存储器访问级的基本互斥性
    • 对内存中的同一个单元同时访问时,必定由存储器进行仲裁使其串行化
      硬件、操作系统或语言未提供任何支持

    采用标志方式,即用标志来表示哪个进程可进入临界区

    • 为每个进程设置相应的标志位
    • 进程在临界区时设置其值为true,不在时为false
    • 进入临界区前先测试其他进程的标志位

    实现临界区管理的软件方法

    Peterson算法

    • 为每个进程设置标志,当标志值为true时表示此进程要求进入临界区
    • 另外,再设置一个指示器turn以指示可以由哪个进程进入临界区
    • 当turn=i时,则可由进程Pi进入临界区

    本质:inside声明自己需要使用, turn谦让其他进程使用

    turn作为共享变量,不可能同时为不同的数,所以一定可以有一方执行。

    实现临界区管理的硬件设施

    关中断

    实现互斥的最简单方法

    • 进入临界区时关中断,进程退出临界区时开中断,这样进程的执行再也不会被打断

    Linux系统:

    • 关中断内核函数:cli()(clear interrupt)
    • 开中断内核函数:sti()(set interrupt)

    关中断方法的缺点

    • 不适合作为通用的互斥机制,关中断的时间过长会影响性能和系统效率
    • 不适用于多处理器系统,一个处理器关中断,并不能防止进 程在其他处理器上执行相同的临界区代码
    • 若将这项权力赋予用户也存在危险,如果用户未开中断,则系统可能因此而终止

    测试并设置指令

    测试并设置机器指令TS(Test and Set)

    • 可把这条指令看做函数,它有布尔型参数x和返回条件码
    • 当TS(&x)测到x值为true时,则置x为false,且根据所测试到的x值形成条件码
    bool TS(bool &x) {
       if(x) {
             x=false; //修改x的值
             return true;
         }
         else //返回条件码,不修改x
            return false;
    }
    

    TS指令实现进程互斥

    • 把一个临界区与一个布尔型变量s相关联
    • 变量s代表临界资源的状态,把它看成一把锁,s的初值置为true,表示没有进程在临界区内,资源可用
    • 系统利用TS指令实现临界区的上锁和开锁原语操作

    本质:TS基于原语单向修改成false,其他进程单项修改成true

    对换指令

    对换指令的功能是交换两个字的内容

    void SWAP(bool &a, bool &b) {
    	bool temp=a;
    	a=b;
    	b=temp;
    	}
    

    SWAP可简单而有效地实现互斥,方法是

    • 为每个临界区设置布尔型锁变量,如lock
    • 当其值为false时,表示无进程在临界区内

    本质:任意时刻只让一个进程拥有false(其实建立在指令为不可分割的最小执行单元?也不太准确,单条指令是否一定会被完整执行和指令本身功能,处理器设计等有关系,所以更好的是把swap理解为原语?)

    信号量与PV操作

    同步和同步机制

    生产者—消费者问题(producer-consumer problem)

    • 是计算机操作系统中并发进程内在关系的一种抽象,是典型的进程同步问题
    • 在操作系统中,生产者进程可以是计算进程、发送进程;而消费者进程可以是打印进程、接收进程等等
    • 解决好生产者—消费者问题就解决好了一类并发进程的同步问题

    生产者和消费者进程的交替执行会导致进程永远等待:

    • 当consumer检测到counter = 0后,进程切换到producer生产产品,但是其wakeup signal在consumer没有睡眠时是无效的,当producer在缓冲区快速生产满产品后会sleep,此时切换回consumer,consumer执行sleep,造成所有进程睡眠等待。

    问题分析

    • 不正确结果并不是因为并发进程共享缓冲区,而是因为它们访问缓冲区的速度不匹配

    解决途径

    • 进程同步:通过交换信号或消息来调整并发进程推进速

    信号量与PV操作

    前面方法解决临界区调度问题的缺点

    • 软件算法:太过复杂,效率低下
    • 硬件方法:采用忙式等待测试法,浪费CPU时间
    • 将测试能否进入临界区的责任推给各个竞争的进程会削弱系统的可靠性,加重用户编程负担

    信号量和P、V操作(E.W.Dijkstra,1965年)

    信号量(semaphore) :一种软件资源

    • 类似交通信号灯机制,让多个进程通过特殊变量展开交互
    • 一个进程在某一关键点上被迫停止执行直到接收到一个对应的特殊变量值
    • 信号量在操作系统中主要用于封锁临界区、进程同步及维护资源计数
    • 操作系统中,信号量表示物理资源的实体,它是一个与队列有关的整型变量
    • 实现时,信号量是一种记录型数据结构,有两个分量
      信号量的值
      信号量队列的队列指针

    信号量只能由同步原语PV对其操作

    • 原语:内核中执行时不可被中断的过程(通常由多条特定指令组成)
    • P操作原语和V操作原语:用于发送和接收信号
    • 若协作进程的相应信号仍未送到,则进程被挂起直至信号到达为止
    • 利用信号量和PV 操作既可解决并发进程竞争问题,又可解决并发进程协作问题

    信号量分类

    按用途分类

    • 公用信号量:联系一组并发进程,相关进程均可在此信号量上执行PV操作
      初值置为1,用于实现进程互斥
    • 私有信号量:联系一组并发进程,仅允许此信号量所拥有的进程执行P操作,而其他相关进程可在其上施行V操作
      初值往往为0或正整数,多用于并发进程同步

    按取值分类

    • 二元信号量:主要用于解决进程互斥问题
    • 一般信号量:又称计数信号量,允许取大于 1的整型值,主要用于解决进程同步问题

    信号量实现互斥

    • 信号量和PV操作可用来解决进程互斥问题
      与TS指令相比较,PV操作也用测试信号量的方法来决定是否进入临界区
      不同的是,PV操作只对信号量测试一次,而TS指令则必须反复测试,造成忙式等待

    信号量解决五个哲学家就餐问题

    哲学家就餐问题:死锁

    解决办法1:

    //至多允许四个哲学家同时吃
    semaphore count=4// sem_t count; sem_init(count, 0, 4);
    semaphore fork[5];//...
    for (int i=0;i<5;i++)
        fork[i]=1;
    Cobegin
       process philosopher_i( ) {/*i= 0,1,2,3,4*/
         while(true) {
            think( );
            P(count);//sem_wait(count)
           	P(fork[i]);//sem_wait(fork[i])
            P(fork[(i+1)%5]);//...
           	eat( );
           	V(fork[i]);//sem_post(fork[i])
            V(fork[(i+1)%5]);//...
            V(count);//sem_post(count)
         }
      }
    coend
    

    解决办法二:

    //取到手边的两把叉子或者一把都不取
    Semaphore mutex=1;
    semaphore fork[5];
    for (int i=0;i<5;i++)
        fork[i]=1;
    Cobegin
       process philosopher_i( ) {/*i= 0,1,2,3,4*/
         while(true) {
            think( );
            P(mutex);
           	P(fork[i]);
            P(fork[(i+1)%5]);
            V(mutex);
           	eat( );
           	V(fork[i]);
            V(fork[(i+1)%5]);
         }
      }
    coend
    

    信号量解决生产者-消费者问题

    生产者-消费者问题:同步问题

    • 一个生产者、一个消费者共享一个缓冲区
    • 多个生产者、多个消费者共享多个缓冲区

    解决基本思路: 可设置两个信号量empty和full,其初值分别为1和0

    • empty :生产者判断能否向缓冲区放入产品
    • full:消费者判断能否从缓冲区取出产品

    在对共享资源操作时,通过mutex的PV操作进出临界区

    记录型信号量解决读者-写者问题

    记录型信号量解决睡眠理发师问题

    管程

    信号量和PV操作缺陷

    • 共享资源的管理分散在各个进程,不利于对临界资源管理
    • 难以防止有意/无意的违法同步操作

    管程(P. Hansen, C. Hoare)引入背景

    • 在进程共享内存的前提下,集中和封装针对一个共享资源的所有访问
    • 把相关的共享变量及其操作集中在一起统一控制和管理,可方便管理和使用共享资源
    • 便于用高级语言来书写程序,也便于程序正确性验证

    管程思想:

    • 把分散在各进程中的临界区集中起来管理,并把共享资源用数据结构抽象地表示
    • 由于临界区是访问共享资源的代码段,建立一个“秘书”程序(管程)管理到来的访问

    管程属性

    • 共享性:管程中的过程可被进程共享
    • 安全性:管程的局部变量只能由该管程的过程访问,管程过程不可访问任何非局部于它的变量
    • 互斥性:任一时刻,最多只能一个进程进入管程

    管程Vs.进程

    • 管程定义的数据结构是公用的,而进程定义的是私有的
    • 管程把共享变量上的同步操作集中起来,而临界区却分散在每个进程中
    • 管程是为管理共享资源而建立的,进程主要是为占有系统资源和实现系统并发性而引入
    • 管程被欲使用共享资源的进程调用,管程和调用它的进程不能并行工作,而进程之间能并行工作,并发性是其固有特性
    • 管程是语言或操作系统的成分,不必创建或撤销,而进程有生命周期,由创建而产生至撤销便消亡

    管程Vs.信号量

    信号量与管程的功能是等价的

    死锁

    如果在一个进程集合中的每个进程都在等待只能由该集合中的其他一个进程才能引发的事件,则称一组进程或系统此时发生死锁

    死锁产生

    • 进程推进顺序不当产生死锁
    • PV操作使用不当产生死锁
    • 资源分配不当引起死锁
    • 临时性资源使用不加限制引起死锁

    不仅与系统拥有的资源数量有关,而且与资源分配策略,进程对资源的使用要求以及并发进程的推进顺序有关

    形成死锁的必要条件

    • 互斥条件(mutual exclusion):进程互斥使用资源
    • 占有和等待条件(hold and wait):进程在请求资源得不到满足而等待时,不释放已占有资源
    • 不剥夺条件(no preemption):又称不可抢占,一个进程不能抢夺其他进程占有的资源
    • 循环等待条件(circular wait) :又称环路条件,存在循环等待链,其中每个进程都在等待链中下一个进程所持资源

    必要条件分析

    • 前3个条件是死锁存在的必要条件,但不是充分条件
    • 第4个条件是前3个条件同时存在时所产生的结果,故条件并不完全独立

    死锁防止(deadlock prevention)

    只要能破坏4个必要条件之一,就可以防止死锁

    • 破坏第一个条件
      使资源可同时访问而不是互斥使用
    • 破坏第二个条件
      静态分配
    • 破坏第三个条件
      采用剥夺式调度方法:申请资源未果时主动释放资源,然后去等待
    • 破坏第四个条件
      采用层次分配策略,将系统中所有资源排列到不同层次中
      一个进程得到某层的一个资源后,只能再申请较高一层的资源
      当进程释放某层的一个资源时,必须先释放占用的较高层资源
      当进程获得某层的一个资源后,如果想申请同层的另一个资源,必须先释放同层中的已占用资源

    按序分配策略:层次策略的变种

    • 把系统的所有资源排一个顺序:系统若共有n个进程,共有m个资源,用ri表示第i个资源,于是这m个资源是r1, r2, ……, rm
    • 规定如果进程不得在占用资源ri(1≤i≤m)后再申请rj(j<i)
    • 按这种策略分配资源时系统不会发生死锁

    死锁避免(deadlock avoidance)

    允许系统中同时存在前三个必要条件,通过合适的资源分配算法确保不会出现进程循环等待链,从而避免死锁

    用银行家算法避免死锁:

    • 操作系统(银行家)
    • 操作系统管理的资源(周转资金)
    • 进程(要求贷款的客户)

    银行家算法——进程启动拒绝法:

    • 系统中若要启动一个新进程工作,其对资源Ri的需求当前系统中所有进程对资源Ri的最大资源需求数加上启动的新进程的最大资源需求数不超过系统拥有的最大数
    • 这个算法考虑最坏的情况,即所有进程同时要使用它们声明的资源最大需求数,因此很难是最优的

    系统性安全的定义:在时刻T0系统是安全的,仅当存在一个进程序列P1, …, Pn,对进程Pk满足公式
    Need[k,i] ≤Available [i]+ ∑Allocation[j,i],k=1, …, n,i=1, …, m

    • 公式左边表示进程Pk尚缺少的资源
    • Available[i](即Vi)是T0时刻系统尚可用于分配且为Pk所想要的那类资源数
    • ∑Allocation[j,i]表示排在进程Pk之前的所有进程所占用的Pk所需要的资源总数
    • 进程Pk所需资源若不能立即被满足,但在所有Pj(j=1,2,…,k-1)运行完成后可以满足
    • 当Pk释放全部资源后,Pk+1也能获得资源以完成任务

    银行家算法

    基本思想

    系统中的所有进程进入进程集合

    • 在安全状态下系统收到进程的资源请求后,先把资源试探性分配给它
    • 系统用剩下的可用资源和进程集合中其他进程还要的资源数作比较
      在进程集合中找到剩余资源能满足最大需求量的进程,从而保证这个进程运行完毕并归还全部资源
      把这个进程从集合中去掉, 系统的剩余资源将更多,反复执行上述步骤
    • 最后检查进程集合
      若为空,表明本次申请可行,系统处于安全状态,可实施本次分配
      否则,有进程执行不完,系统处于不安全状态,本次资源分配暂不实施,让申请进程等待

    死锁检测和解除(deadlock detection and recovery)

    解决死锁问题的一条途径是死锁检测和解除

    • 这种方法对资源分配不加任何限制,也不采取死锁避免措施
    • 系统定时地运行死锁检测程序,判断系统内是否已出现死锁
    • 如果检测到系统已发生死锁,再采取措施解除它:基于进程—资源分配图

    进程-资源分配图

    • Pi→Rj为请求边,表示进程Pi申请资源类Rj中的一个资源得不到满足而处于等待Rj类资源的状态
    • Rj→Pi为分配边,表示Rj类中的一个资源已被进程Pi占用

    确定死锁的方法:

    • 如果进程-资源分配图中无环路,则此时系统没有发生死锁
    • 如果进程-资源分配图中有环路,且每个资源类中仅有一个资源,则系统中发生死锁。此时,环路是系统发生死锁的充要条件,环路中的进程便为死锁进程
    • 如果进程-资源分配图中有环路,且涉及的资源类中有多个资源,则
      环路的存在只是产生死锁的必要条件而不是充分条件

    进程-资源分配图简化:

    • 如果能在进程-资源分配图中消去此进程的所有请求边和分配边,成为孤立结点
    • 经一系列简化,使所有进程成为孤立结点,则该图是可完全简化的;否则则称该图是不可完全简化的

    死锁定理

    • 系统为死锁状态的充分条件是当且仅当该状态的进程-资源分配图是不可完全简化的

    死锁检测vs死锁避免

    • 死锁避免算法考虑检查每个进程还需要的所有资源能否满足
    • 死锁检测算法仅要根据进程的当前申请资源量来判断系统是否进入不安全状态

    死锁解除

    • 结束所有进程的执行,重新启动操作系统
      方法简单,但以前工作全部作废,损失很大
    • 撤销所有死锁进程,解除死锁继续运行
      逐个撤销陷于死锁的进程,回收其资源重新分派,直至死锁解除
    • 剥夺死锁进程占用资源,但并不撤销它,直至死锁解除
      可仿照撤销陷于死锁进程的条件来选择剥夺资源的进程

    根据系统保存的检查点,让所有进程回退,直到足以解除死锁
    这种措施要求系统建立保存检查点、回退及重启机制

    检测到死锁时,如果存在未卷入死锁的进程,随着这些进程执行结束后有可能释放足够的资源来解除死锁

    进程通信

    并发进程之间的交互必须满足两个基本要求:同步和通信

    进程通信IPC(InterProcess Communication):进程之间互相交换信息的工作

    Unix基本通信机制

    • 信号(signal)通信机制
    • 管道(pipeline)通信机制
      System V IPC通信机制
    • 消息传递(message passing)通信机制
    • 信号量(semaphore)通信机制
    • 共享内存(shared memory)通信机制

    进程通信的发展

    UNAT&T的Bell与加大伯克利的BSD是两大主力

    • Bell致力于改进传统的进程IPC,形成了SYSTEM Ⅴ IPC机制
    • BSD在改进IPC的同时,把网络通信规程(TCP/IP)实现到UNIX内核中,出现了socket网络通信机制

    信号通信机制

    软中断 :

    • 中断与异常要通过硬件设施来产生中断请求,称为硬中断
    • 不必由硬件产生中断源而引发的中断称为软中断
    • 软中断是利用硬中断的概念,采用软件方法对中断机制进行模拟,实现宏观上的异步执行
    • “信号”是一种软中断机制

    中断机制vs.信号机制

    相同点

    • 两者在概念上是“一致”的
    • 两者都是“异步”的
    • 两者均采用“向量表”实现
    • 两者均有“屏蔽”设施

    不同点

    • 前者由硬件和软件相结合来实现,后者则完全由软件实现
    • 中断向量表和中断处理程序(全部由系统提供)均位于系统空间
    • 信号向量表虽然处于系统空间,但信号处理程序由应用程序提供,并在用户空间执行

    在这里插入图片描述

    管道通信机制

    管道(pipeline)是连接读写进程的一个特殊文件

    • 允许进程按先进先出方式传送数据,也能使进程同步执行操作
    • 发送进程以字符流形式把大量数据送入管道,接收进程从管道中接收数据,所以叫管道通信
    • 管道的实质是一个共享文件,基本上可借助于文件系统的机制实现,包括
      (管道)文件的创建、打开、关闭和读写

    匿名管道

    匿名管道是半双工的

    • 数据只能向一个方向流动
    • 要求双向通信时,需要建立两个匿名管道

    只能用于具有亲缘关系的进程通信

    • 亲缘关系指具有共同祖先,如父子进程或者兄弟进程之间

    匿名管道对于管道两端的进程而言,是一个特殊文件

    • 写入的内容每次都添加在管道缓冲区的末尾,每次都是从缓冲区的头部读出数据

    有名管道

    又称FIFO,克服只能用于具有亲缘关系的进程之间通信的限制

    • FIFO提供一个与路径名的关联,以FIFO的文件形式存在于文件系统中,通过FIFO不相关的进程也能交换数据
    • FIFO遵循先进先出,对管道及FIFO的读总是从开始处返回数据,对它们的写则把数据添加到末尾

    共享内存通信机制

    指两个或多个进程共同拥有一块内存区,该区中的内容可被进程访问

    消息传递通信机制

    在不同进程之间传递数据的机制

    • 消息传递的复杂性
      进程地址空间隔离,发送进程无法将消息直接复制到接收进程的地址空间中,只能由操作系统完成
    • 消息传递基本原语(阻塞/同步问题)
      发送消息:向一个给定目标进程发送一条消
      接收消息:从一个给定源进程接收一条消息
    • 消息传递特点
      正在执行的进程间可在任何时刻发送/请求消息
      消息传递机制与进程的阻塞和释放紧密联系
      一个进程在某一时刻的执行依赖于另一进程的消息或等待其他进程对发出消息的回答
      消息传递提供了进程同步能力,进一步扩充了并发进程间对数据的共享

    间接通信

    • 支持消息传递异步通信的形式
    • 进程之间发送或接收消息通过共享数据结构信箱进行
    • 间接通信基本原语
      send(A,信件):把一封信件(消息)传送到信箱A
      receive(A,信件):从信箱A接收一封信件(消息)

    基于消息传递的进程通信同步

    send()操作

    • 同步/阻塞:发送进程执行send()后,等待接收进程回答消息后才继续进行
    • 异步/非阻塞:发送进程执行send()后,将消息传送到接收进程的信箱后继续运行,直到某个时刻需要接收进程送来回答消息时,才查询和处理

    receive()

    • 同步/阻塞:接收进程执行receive()后直到消息交付完成,都处于等待消息的状态
    • 异步/非阻塞:执行receive()后不要求接收进程等待,当它需要消息时,再接收并处理消息

    通信进程常用同步组合方式

    • 阻塞型send和阻塞型receive
      同步通信、可靠通信
    • 非阻塞型send和非阻塞型receive
      设置消息队列容纳消息数
    • 非阻塞型send和阻塞型receive
      发送进程可把一条或多条消息发给目标进程
      接收进程通常是服务器进程,平时处于阻塞状态,直到发送进程发来消息才被唤醒

    System V IPC

    IPC资源

    • 表示单独的消息队列、共享内存或信号量集合

    具有相同类型的接口函数

    • 信号量实现进程同步
    • 消息队列以异步方式为通信频繁、但数据量少的进程通信提供服务
    • 共享主存为数据量大的进程间通信提供服务

    共同点

    • 通过 System V IPC对象通信时,需传递该对象的唯一IPC标识符
    • 访问System V IPC对象时必须经过许可检验
    • System V IPC对象的访问权限由对象创建者设置
    • IPC通信机制将IPC标识符作为对系统资源表的索引

    条件变量

    利用线程间共享的全局变量实现同步
    条件变量使线程睡眠等待特定条件出现(无需轮询)
    使用方法

    • 通常条件变量和互斥锁同时使用
    • 一个线程因等待“条件变量的条件成立”而挂起
    • 另一个线程使"条件成立"(给出条件成立信号)

    Linux同步和通信机制

    • 原子操作:原子操作执行时不被打断,防止竞争条件的发生
    • 等待队列:Linux内核信号量采用非忙式等待来实现
      进程执行down()操作而等待时,将被放入等待信号量队列
      等待队列也是临界资源,对其进行修改时应加锁
      内核为每个事件都设立一个等待队列
    • 内核信号量:一般信号量(使用等待队列机制);读者/写者信号量,写进程每次唤醒一个,读进程每次唤醒多个
    • 自旋锁:原子操作能保证对变量操作的原子性,在单步内完成,但临界区可以跨越多个函数,原子操作对此无能为力 ,例如:
      先从一个数据结构中读取数据,对其进行格式转换和解析,再写到另一个数据结构中
      整个执行过程必须是原子的,数据更新完毕前,不能有其他代码读取这些数据
      自旋锁分为:一般自旋锁、读者-写者自旋锁
    • 关中断:关中断是把内核态执行的程序段作为一个临界区来保护
      ,主要保护中断处理程序也要访问的数据结构。
      关中断还能禁止内核抢占
      为防止死锁,关中断期间内核不能执行阻塞操作
      在SMP环境中,关中断只能防止来自本机其他中断处理程序的并发访问,需要引入自旋锁在禁止本地中断的同时,防止来自其他机器的并发访问

    一般自旋锁:

    • 最多只能被一个可执行线程持有
    • 自旋锁采用忙式等待,直至资源被解锁 ;二值信号量不必循环等待信号量,而是进入等待队列

    读者写者自旋锁:
    多进程可以并发地持有读锁,写锁仅有一个进程能持有

    自旋锁作用:在SMP系统中,自旋锁最重要的特点是内核例程在等待锁被释放时一直占据着某个 CPU,用来保护那些只需简短访问数据结构的操作,如
    从双向队列链表中增加或删除一个元素
    因此,在内核需要进程同步的位置,自旋锁使用得比较频

    Linux操作系统内核执行过程中,会造成并发执行,应提供多种内核同步机制

    • 中断及异步信号:随时可能打断正在执行的内核代码
    • 可抢占:如果内核具有抢占性,运行的内核任务会被另一个任务抢占
    • SMP系统:两个或多个CPU同时执行内核代码,访问同一共享数据结构

    操作系统并发问题解决方案小结

    在这里插入图片描述

    展开全文
  • 异步性:由于进程间的相互制约,使进程具有执行的间断性,即进程按各自独立的、不可预知的速度向前推进结构特征:进程由程序、数据和进程控制块三部分组成。多个不同的进程可以包含相同的程序:一个程序在不同...
  • 进程之间相互独立,可实现并行,多线程只能并发执行,实际还是顺执行,只是在同一时间片段,假似同时执行,cpu可以按时间切片执行,单核cpu同一个时刻只支持一个线程执行任务,多线程并发事实上就是多个线程排队申请...
  • 顺序编程,里面所有事物都只能按照...并发编程有两个好处,一个是提高应用程序执行速度,一个是对于有些程序,可以提供方便易用模型。但是并发编程也有很多问题,并行任务很容易互相干扰,这就导致很多问题出...
  • 而机房间专线对单个scp进程的传输速度是有限制,比如最大在100Mb/s,如果直接启动100个scp,则又会遇到ssh的并发连接数限制。 所以需要控制并发数,即不超过ssh的并发限制,又要让单网卡上带宽接近饱和,尽快...
  • 多个进程可以实现并发效果,也就是说,当我们程序中存在多个进程的时候,在某些时候,就会让程序的执行速度变快。我们可以借助python中强大模块。来实现创建进程这个功能。1、multiprocessing模块把所有和进程...
  • 并发指的是多个程序看上去被同时执行,这是因为cpu在多个程序之间不停的进行切换,且切换的速度十分快,让我们觉得自己在共享这段时间,所以不是真正意义上的同时 2、阻塞与非阻塞 阻塞: 当程序在执行过程中遇到...
  • 为了解决手工操作带来的低效,批处理操作系统应运而生,批处理就是先把要执行的指令预先写下来,(写到纸上,磁盘,磁带等等),形成一个指令清单,这个指令清单就是我们说的任务,然后将任务交给计算机去执行,批处理操作系统...
  • 并行:一个时间段里同时执行多个进程 一个单核的 CPU,它每次只能执行一个进程,多核的CPU可以同时执行多个进程,就是并行。 并发:一个时间点同时执行多个进程 ...线程:进程里面执行的每一个任务,线程是程序 CP...
  • 线程:线程是进程一部分,是进程执行过程中一个分支路径。若将进程类比为一颗树,主线程则是树树干,其他分线程是一个个细小树枝,从主线程分离出来继续执行。 并行:指多个事件在同一时间被同时执行。 ...
  • 进程的特征: --动态性:进程的实质是程序在多道...--异步性:由于进程间的相互制约,使进程具有执行的间断性,即进程按各自独立的、不可预知的速度向前推进 --结构特征:进程由程序、数据和进程控制块三部分组...
  • 并发:指的是任务数多余cpu核数,通过操作系统的各种任务调度算法,实现用多个任务“一起”执行(实际上总有一些任务不在执行,因为切换任务的速度相当快,看上去一起执行而已) 并行:指的是任务数小于等于cpu核数...
  • 线程可以理解为是进程中的执行的一段程序片段。 一个进程可以包含多个线程。 例如打开电脑管家:则为打开一个进程 电脑管家中有:清理,病毒查杀,驱动检测等多个功能,这些功能就是多个线程。 进程可以为并行,线程...
  • 多线程(并发执行

    2020-08-02 15:06:54
    并发不是真正意义上“同时进行”,只是将CPU划分成好几个时间片段,每个片段内执行一个任务,然后在这几个片段之间来回切换,由于CPU处理速度快,让用户感觉像是多个任务在同时执行。 区别: 并行是某一时刻,...
  • 1,并行和并发有什么区别 并行:多个处理器或多核处理器同时处理多个任务。 并发:多个任务在同一个CPU...一个进程下至少有一个线程,一个进程下也可以有多个线程来增加程序的执行速度。 3.守护线程是什么? 守护线程...
  • 操作系统增加了进程、线程,以分时复用CPU,进而均衡CPU与I/O设备的速度差异; 编译程序优化指令执行顺序,使得缓存能够更加合理的利用。 并发程序的问题根源 1.缓存导致的可见性问题 单核时代:所有的线程都是...
  • 多任务的目的:提升程序的执行效率,更充分利用cpu的资源并行:当任务数小于或者等于cpu核数时,每一个任务都有对应的cpu来处理执行,即任务真的是一起执行的并发:当任务数多于cpu核数,通过操作系统的各种任务调度...
  • 其实并发有点类似于多线程的原理,多线程并非是同时执行多个任务,如果你开两个线程执行,就是在很快的速度下不断的切换这两个任务,已达到"同时执行效果"。 所以他们两个的区别就是:一个是交替执行,一个是同时执行...
  • 一起来探索JAVA奥秘一并发编程简介什么是并发编程并发历史早期计算机从头到尾执行一个程序,浪费资源,效率低 操作系统出现后,计算机能运行多个程序,不同程序在不同单独进程中运行。一个进程有多个线程,提高...
  • 计算机原理并发:多个任务如果被分配给了一个CPU内核,多任务之间是并发关系,多个任务之间并不是真正“同时”并行:多个任务如果被分配给了不同CPU内核,多任务之间执行就是并行关系CPU:计算机硬件核心部件,...
  • 1.2.2 大型网站技术和java中间件-分布式系统的基础知识-线程和进程执行模式 ...P指的是程序可并行部分在单核上的执行时间占比,N表示cup处理器个数(总核心数),S(N)指N个处理器相对在单核处理的速度提升比。 N ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 934
精华内容 373
关键字:

并发进程执行的速度是