精华内容
下载资源
问答
  • 并发执行与时间有关的错误
    2022-06-12 01:45:32

    首先我们先看一下错误的案例

       /**
         * 按照顺序执行携程
         */
        @Test
        fun `test sync`() = runBlocking {
            //统计函数执行时间
            val userTime = measureTimeMillis {
                val one = doOne()
                val two = doTwo()
                println("相加之和为:${one + two}")
            }
            println(" userTime ${userTime}")
    
        }
    
        private suspend fun doOne(): Int {
            delay(1000)
            return 14
        }
    
        private suspend fun doTwo(): Int {
            delay(1000)
            return 15
        }

    2s多

    那我们肯定是想在1s左右处理完。这明显有些耗时间。。如何优化呢

    改为并发执行

     /**
         * 按照顺序执行携程
         */
        @Test
        fun `test sync`() = runBlocking {
            //统计函数执行时间
            val userTime = measureTimeMillis {
                val one = async { doOne() }
                val two = async { doTwo() }
                println("相加之和为:${one.await() + two.await()}")
            }
            println(" userTime ${userTime}")
    
        }

    如何改为并发执行呢?

    但是千万不要使用这种写法

        //错误示范
                    val time3 = measureTimeMillis {
                        val one = async { doOne() }.await()
                        val two = async { doTwo() }.await()
                        Log.e(TAG, "the 3 result:${one + two}")
                    }
                    Log.e(TAG, "Completed 3 in $time3 ms")
    

    否则还会是2s

    ​​​​​​​

    更多相关内容
  • 对于单核处理器来说,并发进程并不是多个进程同时占用处理器同时执行,而是同时装入主存,至于进程什么时候被执行,这要看进程的调度策略啦! 谈到并发进程,我就想到进程的并发会产生许多错误,这些错误在我们在...

        在多道程序设计的系统中同时存在着许多进程。他们可能同时装入主存,等待处理器的调度,这就形成的并发进程。对于单核处理器来说,并发进程并不是多个进程同时占用处理器同时执行,而是同时装入主存,至于进程什么时候被执行,这要看进程的调度策略啦! 谈到并发进程,我就想到进程的并发会产生许多错误,这些错误在我们在设计系统或者编写软件时都是尽量要避免的。 

        那么进程的并发执行为什么会产生错误那?归根到底是并发进程访问共享变量的事,当多个进程访问共享变量的过程中,就有可能会产生与时间有关的错误,或者是死锁。

        一、导图分析


       二、导图分析

       说到进程访问共享资源,我觉得首先先明白进程的同步与进程的互斥问题。

       1、进程的互斥:指当有若干个进程都要使用某一共享资源时,任何时候最多只允许一个进程去使用共享资源,其他要使用的进程必须等待,知道该资源的占用者释放了该资源。

       2、进程的同步:在并发进程之间存在一种制约关系,一个进程的执行依赖另一个进程的消息,当一个进程没有得到另一个进程的消息时应该等待,知道消息到达后才被唤醒。

       3、与时间有关的错误:多个进程共同执行时,交替的访问了共享变量,但是有一个进程由于自身原因或者外界原因被中断了后,稍后又接着执行,最后导致运行结果出错。

       例如:

       某小区有两扇门,其中一扇门是入口,另一扇门是出口,用一个计数器count显示在小区的人数,当有人进入时,由进程PIN实现计数加一,当有人退出时,由进程POUT减一。这两个进程如下

    <span style="font-family:KaiTi_GB2312;font-size:18px;">begin
         count: interge                                                               
         count: =0
    cobegin
    process PIN 
         R1: integer;
    begin
         R1:=count;
         R1:=R1+1;
         count: =R1;
    end ;
    
    process POUT 
         R2: integer;
    begin
         R2:= count;
         R2:=R2-1;
         count:=R2;
    end;
    coend;
    end;</span>
        假定某个时候的计数值count=n,这时有一个人要进入,正好有一个同时要出去,于是进程PIN和POUT同时都要执行,如果进程PIN和POUT都没有被打断,那么各自完成了count+1和count-1操作,count还是n,但是若果被打断了PIN操作,看下图



    这样执行过后,结果会变成n+1,这就是与时间有关的错误的实例。

        解决办法:采用PV操作,引进PV操作会引进一个叫临界区的名词,临界区是指并发进程中与共享变量有关的程序段。相关临界区是指并发进程中设计到相同变量的那些临界区。PV操作的原理是保证一个进程在临界区执行时,不让另一个进程进入相关临界区执行,即个进程对共享变量的访问是互斥的,这就不会造成与时间有关的错误。对于上面表格的一个例子来说,当进程PIN被打断后,POU不能访问共享变量count,直到PIN进程结束后才让POUT访问,这样最后的结果就正确了。

       三、小结

        解决并发进程之间的错误关键就是解决共享变量的访问方式,当多个进程都想访问共享变量时,我们一定要管理好各个进程的使用规律,不然的话程序就会出错。采用PV操作,让相关进程互斥的进入各自的临界区执行,这样就解决了并发进程间与时间有关的错误。好了,并发进程访问共享变量时,还会产生死锁,要想看死锁的形成原因及解决办法,请关注我的下一篇博客!

    展开全文
  • 进程并发与同步

    2012-07-06 09:59:46
    1、 加深对进程概念的理解,区分进程并发执行与串行执行。 2、 掌握进程并发执行的原理,理解进程并发执行的特点。 3、 了解fork( )系统调用的返回值,掌握用fork()创建进程的方法;熟悉wait、exit等系统调用。 能...
  • 操作系统作业答案.pdf

    2020-02-10 16:09:59
    习题一 1举例说明为什么对并发执行的程序不加控制会产生与执行时间有关错误 解程序在并发执行时由于资源是共享的而且常常资源数少于程序对这些资源的需求数致使这些并发执行的程 序之间因为竞争资源导致存在间接...
  • 多个请求并发执行怎么写?

    千次阅读 2020-09-22 09:09:15
    编者注:在前端开发中,多个请求并发执行很常见,但遇到时会有点头痛,原因是异步执行时要知道请求是否结束,并开始下一步,本文分享了多个请求并发执行怎么写,一起来看看吧。作者:vczhan来源...

    编者注:在前端开发中,多个请求并发执行很常见,但遇到时会有点头痛,原因是异步执行时要知道请求是否结束,并开始下一步,本文分享了多个请求并发执行怎么写,一起来看看吧。

    作者:vczhan

    来源:https://segmentfault.com/a/1190000019895597

    最近在写一个Node.js程序,功能是下载页面上的资源,首先拿到页面资源链接列表,如:

    [
      'https://xxx.com/img/logo.jpg',
      'https://xxx.com/img/bg.jpg',
      'https://xxx.com/css/main.css',
      'https://xxx.com/css/animate.css',
      'https://xxx.com/js/jquery.js',
      'https://xxx.com/js/form.js',
      ...
    ]

    要求是资源并行下载,所有资源下载结束后通知,收集错误的下载链接。

    如果是传统做法是遍历数组发送请求,声明一个变量记录请求数,不管成功或失败,结束后都给这个变量+1,并且调用一个函数,这个函数判断当前变量是否等于数组长度,相等则表示所有请求已经完成。

    // pseudo code
    var count = 0
    var errs = []
    var data = [...]
    function request(url) {
      ajax({url: url})
        .success(function () {
           count++
           callback()
        })
        .fail(function () {
          count++
          errs.push(...)
          callback()
        })
    }
    
    function callback() {
      if (count === data.length) {
        console.log('done!')
      }
    }
    
    data.forEach(request)

    因为请求是异步的,我们也无法确定每个请求花费的时间,所以只能在回调里处理。现在我们有了Promiseasync-await,支持同步的写法,那可以怎么写呢?


    我们用setTimeout来模拟请求,数据data = [500, 400, 300, 200, 100]既是每个请求返回的数据也是每个请求所需的时间。

    如果是继发请求(一个请求结束后再请求后一个),那么应该是按顺序打印,理论上所有请求的总时间等于每个请求所花时间之和,约等于1500ms;如果是并发请求(假设请求数不会太多,不超过限制),顺序是按时间从小到大打印,理论上所有请求的总时间等于最长的那个时间,约等于500ms

    首先先看下怎么并行请求和请求结束确定

    // 模拟请求
    function request(param) {
      return new Promise(resolve => {
        setTimeout(() => {
           console.log(param)
           resolve()
        }, param)
      })
    }
    const items = [500, 400, 300, 200, 100]

    ✘ 直接for循环

    (() => {
      for (let item of items) {
        request(item)
      }
      console.log('end')
    })()
    // 输出:end, 100, 200, 300, 400, 500

    上面的输出可以看出,请求是并行的,但是无法确定什么结束

    ✘ for循环,使用async-await

    (async () => {
      for (let item of items) {
        await request(item)
      }
      console.log('end')
    })()
    // 输出:500, 400, 300, 200, 100, end

    上面的代码可以看出,虽然确定了结束,但请求是继发的

    ✔ 使用Promise.all

    (() => {
      Promise.all(items.map(request)).then(res => {
        console.log('end')
      })
    })()
    // 输出:100, 200, 300, 400, 500, end

    上面的代码可以看出,请求是并发的,并且在所有请求结束后打印end,满足条件

    我们不能保证所有的请求都是正常的,接下来看看当有请求出错时怎么处理,假设200的请求出错

    function request(param) {
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          if (param === 200) {
            // console.log(param, ' failed')
            return reject({
              status: 'error',
              data: param
            })
          }
          // console.log(param, ' success')
          resolve({
            status: 'success',
            data: param
          })
        }, param)
      })
    }
    const items = [500, 400, 300, 200, 100]

    Promisecatch方法捕获错误,最近新增的finally方法能在最后执行

    (() => {
      Promise.all(items.map(request))
        .then(res => {
          console.log(res)
        })
        .catch (err => {
          console.log(err)
        })
        .finally(res => {
          console.log('end', res)
        })
    })()
    // 输出 {status: "error", data: 200}, end, undefined

    上面的输出可以看出,如果有错误,则不会进入then,而是进入catch,然后进入finally,但是finally不接受参数,只告诉你结束了。如果把上面模拟请求的console.log(...)注释去掉,还会发现finally是在catch结束后就执行了,而200后面的请求还未结束。

    接下来我们改造下模拟请求,在请求出错后就catch错误

    function request(param) {
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          if (param === 200) {
            // console.log(param, ' failed')
            return reject({
              status: 'error',
              data: param
            })
          }
          // console.log(param, ' success')
          resolve({
            status: 'success',
            data: param
          })
        }, param)
      }).catch(err => err)
    }
    
    (() => {
      Promise.all(items.map(request))
        .then(res => {
          console.log(res, 'end')
        })
    })()
    // 输出 [{…}, {…}, {…}, {stauts: 'error', data: 200}, {…}], end

    这样就可以在then中拿到全部的结果了,如果要用for循环的话也是可以的

    (async () => {
      const temp = []
      // 这个for循环的作用和上面的map类似
      for (let item of items) {
        temp.push(request(item))
      }
    
      const result = []
      for (let t of temp) {
        result.push(await t)
      }
      console.log(result, 'end')
    })()
    // 输出与上面一致

    第一个for循环保证并发请求,保存了Promise,第二个循环加入await保证按顺序执行。

    好了,以上就是全部内容,你有更好的写法吗?

    最后

    看完点个赞,分享一下吧,让更多的朋友能够看到。如果你喜欢前端开发博客的分享,就给公号标个星吧,这样就不会错过我的文章了。

    好文和朋友一起看~

    展开全文
  • 可再现性:结果执行速度无关,只初始条件有关。给定相同的输入,输出结果一定相同。 顺序执行给程序员检测和纠正错误带来便利。 并发执行:多道程序系统执行环境的变化可以引起多道程序的并发执行。一组在逻辑...

    程序的顺序执行和并发执行

    顺序执行:按照顺序进行执行。

    • 顺序性:严格按照顺序执行,前一个结束后一个才能执行
    • 封闭性:程序运行时独占资源,只有程序本身才能改变机器各种资源的状态。
    • 可再现性:结果与执行速度无关,只与初始条件有关。给定相同的输入,输出结果一定相同。

    顺序执行给程序员检测和纠正错误带来便利。

    并发执行:多道程序系统执行环境的变化可以引起多道程序的并发执行。一组在逻辑上相互独立的程序或程序段在执行过程中其执行时间在客观上相互重叠,即一个程序尚未结束、另一个程序的执行已经开始的执行方式。
    链接:多道程序系统的具体概念

    • 间断性:共享资源的使用使得在并发程序之间有相互制约。相互制约导致并发程序具有:执行-暂停-执行 这种间断性的活动规律。
    • 失去封闭性:多个程序共享资源,执行时必定会受到其他程序的影响。
    • 不可再现性:失去封闭性,也同时失去了不可再现性。资源的利用状况和环境有关,不能保证每次同一个输入有着相同的输出。

    进程的概念

    程序的概念:源代码是静态文本,通过编译软件对源代码进行编译之后得到程序。
    进程的定义:程序是静态的,程序每一次执行的动态过程都不一样。只用程序这一概念,只能对并发程序进行静止的、孤立的研究,不能深刻地反映它们活动的规律和状态变化。所以有了进程这一说法。程序——静态,进程——动态,进程就是程序的执行过程

    进程特性

    动态性:由创建而产生、由调度而执行、因得不到资源而暂停执行、由撤销而消亡。进程具有一定的生命周期。

    并发性:并发性是指多个进程实体同存与主存中,能在一段时间内同时运行,并发性是进程和操作系统的重要特征。引入并发执行的目的是使其程序能够和其他进程的程序并发执行,但是程序本身并不能并发执行。

    独立性:进程实体是一个独立运行的基本单位,也是系统中独立获得资源和独立调度的基本单位。进程和程序并非一一对应,一个程序在不同的数据集上就能构成不同的进程。

    异步性:进程按照各自独立的,不可预知得速度向前推进

    结构特征:进程实体是由:程序段、数据段及程序控制快三部分组成

    进程的基本状态和转换

    进程具有异步性,所以有 执行-暂停-执行 的活动规律。
    一个进程活动期间有三种基本状态:就绪状态、运行状态、等待状态。

    1)就绪状态:进程已经分配到只差CPU以外的所有必要资源。在系统中,多个进程同时处于就绪状态排成的队列叫做就绪队列。

    2)运行状态:运行状态是指进程已获得处理器,其程序正在执行。单处理器系统中只能有一个进程。

    3)等待状态:进程因发生某些事件(比如请求输入输出、申请缓存空间等)而暂停执行的状态。多个进程同时处于等待状态的队列叫等待队列,多个等待原因可以排成多个队列。

    在这里插入图片描述

    • (1)就绪→运行状态
      处于就绪状态的进程,当进程调度程序为之分配了处理器后,该进程便由就绪状态转换为运行状态。正在执行的进程也称为当前进程。
    • (2)运行→等待状态
      正在执行的进程因出现某事件而无法执行时,就释放处理器转换为等待状态。例如,进程请求访问临界资源,而该资源正被其它进程访问,则请求该资源的进程将由运行状态转变为等待状态。
    • (3)运行→就绪状态
      在分时系统中,正在执行的进程,如因时间片用完而被暂停执行,该进程便由运行状态转变为就绪状态。又如,在抢占调度方式中,一个优先权高的进程到来后,可以抢占一个正在执行的优先权低的进程的处理器,这时,该低优先权进程也将由运行状态转换为就绪状态。
    • (4)等待→就绪状态
      处于等待状态的进程在等待事件结束后就转换成就绪状态,等待处理器的分配。

    有些操作系统中增加了两种基本状态:新状态和终止状态
    在这里插入图片描述

    • 新状态指的是刚刚建立,还没有将它送入就绪队列时的状态。
    • 终止状态是指的是一个进程已经结束,但是还没有将它撤销时的状态。

    进程控制块

    每一个进程都有一个进程控制块(PCB)。进程控制块是操作系统用与记录和刻画进程状态及有关信息的数据结构,也是操作系统控制和管理的主要依据。

    作用:使一个在多道程序下不能独立运行的程序(含数据),成为一个能独立运行的基本单位、一个能与其他进程并发执行的进程。

    操作系统是根据PCB来对并发执行的进程进行控制和管理的

    在这里插入图片描述
    标识信息:每一个进程都有一个唯一的标识符。

    说明信息:说明本进程的情况。

    现场信息:当进程由于某种原因让出处理器的时候,把与处理器有关的各种现场信息保留下来,以便于后续该进程重新获得处理器之后能够把保留的现场信息重新置入处理器的想过寄存器之中继续执行。

    管理信息:对进程进行管理和调度的信息。

    进程队列

    定义:把处于相同状态的进程链接在一起,形成的队列就叫做进程队列。处于就绪状态的叫就绪队列,等待状态的叫等待队列。

    链接方式实现进程队列
    进程控制块能够标识进程的存在,并动态刻画进程的特性,所以进程队列可以用进程控制块的链接来形成。

    链接方式有:单向链接和双向链接。
    在这里插入图片描述

    • 一个进程从所在的队列中退出称为“出队”
      一个进程能被选中占用处理器时,就从就绪队列中退出成为“执行态”

    • 一个进程进入到指定的队列中称“入队”
      进程要求读磁盘上的信息而成为等待磁盘传输信息的状态,便进入等待队列。

    索引方式形成进程队列
    建立索引表,表内填有各个PCB的地址
    在这里插入图片描述

    展开全文
  •  从根本上讲,我们必须保证数据库查询和执行查询的连接必须能够在并发执行中没有错误(如死锁或更新冲突),并能在可接受的等待时间内得到结果。如果不能做到,要定位并发问题并找出原因:为什么独立运行查询时...
  • 进程管理顺序执行和并发执行

    千次阅读 2018-09-15 13:15:00
    一、引言 在传统的操作系统中,程序并不能独立运行,...顺序执行:通常可以把一个应用程序分成若干个程序段,在各程序段之间,必须按照某种先后次序顺序执行,仅当前一操作(程序段)执行完后,才能执行后继操作。...
  • java中使用线程池并发执行方法

    万次阅读 2018-11-20 17:36:40
    我们在开发的过程中,会经常遇到并发执行某个方法。在网上搜索答案的时候,都似乎Thread创建线程,或者就是先给你来一套JMM,线程之间内存,消息通信机制。 这种做法很好,巩固知识,如果现在就像要一个案例多线程...
  • 互斥是指并发执行的多个进程由于竞争同一资源而产生的相互排斥关系。 2-直接互相制约欢喜(合作)-同步 进程之间共同完成一项任务直接发生相互作用的关系。 临界资源临界区 临界资源指打印机,磁带机,表格 。...
  • 与时间有关错误可以这样描述:程序并发执行时若共享了公共变量,其执行结果将并发程序执行的相对速度有关,即给定相同的初始条件,也可能会得到不同的结果,此为与时间有关错误。 转载于:...
  • 进程之间的相互影响 并发进程相互之间可能是无关...进程执行与时间有关错误 进程执行与时间有关错误 进程的执行的速度不能由自己来控制,对于有交往的并发进程来说,可能有若干并发进程同时使用共享资源。即一个进
  • 一:程序并发执行 特征:只有不存在前趋关系的程序之间才有可能并发执行,否则无法并发执行。 例:输入程序、计算程序和打印程序之间,存在着Ii->Ci->Pi的前趋关系。对一批作业进行处理,输入程序I1在输入第...
  • 在实际工作中,错误使用多线程非但不能提高效率还可能使程序崩溃。以在路上开车为例: 在一个单向行驶的道路上,每辆汽车都遵守交通规则,这时候整体通行是正常的。『单向车道』意味着『一个线程』,『多辆车』意味...
  • JavaWeb 并发编程 并发解决方案

    万次阅读 多人点赞 2018-09-12 03:41:00
    在这里写写我学习到和自己所理解的 Java高并发编程和高并发解决方案。现在在各大互联网公司中,随着日益增长的互联网服务需求,高并发处理已经是一个非常常见的问题,在这篇文章里面我们重点讨论两个方面的问题,一...
  • SpringBoot中通过@Scheduled注解开启定时任务,通过控制执行顺序,单线程和多线程下同时执行多个定时任务所导致的并发问题。
  • 数据库并发与并发异常

    千次阅读 多人点赞 2020-05-24 18:25:41
    本文关键字:脏读、脏写、更新丢失、...在使用数据库来支撑业务系统时,随着用户量的增大,经常会遇到同时读取相同数据的情况,在没有进行并发控制的情况下就会遇到各种各样的问题,对于可能出现的问题我们要有所了解。
  • 关于存储过程并发处理解决方案

    千次阅读 2021-05-02 01:28:07
    当前位置:我的异常网» Oracle开发»关于存储过程并发处理解决方案关于存储过程并发处理解决方案www.myexceptions.net网友分享于:2013-01-05浏览:116次关于存储过程并发处理想测试一下存储过程处理过程中,另一个...
  • Java并发与并行

    2021-01-27 08:04:48
    并发是指同时执行多项操作的能力。 早在早期,计算机一次只能执行一个程序。但是现在,现代计算机能够同时运行很多任务。例如 - 您可以同时在网络浏览器上浏览我的博客,并在媒体播放器上听音乐。 您可以...
  • Python 并发编程

    千次阅读 2022-01-05 00:22:17
    并发(concurrency):指在同一时刻只能有一条指令执行,但多个进程指令被快速的轮换执行,使得在宏观上具有多个进程同时执行的效果,但在微观上并不是同时执行的,只是把时间分成若干段,使多个进程快速交替的执行。...
  • jqury 解决多个Ajax并发执行

    千次阅读 2018-04-20 16:52:59
    解决多个Ajax并发执行。 更多前端信息可以关注博客:http://www.colbrus.com  通常 为了减少页面加载时间,先把核心内容显示处理,页面加载完成后再发送ajax请求获取其他数据,这时就可能产生多个ajax请求,为了...
  • 浅谈并发测试

    2022-02-21 13:44:44
    fiddler并发-多条 步骤: 打上断点 找到接口,右键Replay-shift+Reissue Requests,弹框填写100 点击ok,在列表出现100条url 点击go,进行并发 fiddler并发-2条 步骤: 打上断点 找到要并发的接口,右键Replay-...
  • 什么是响应时间并发数,吞吐量?

    万次阅读 多人点赞 2019-04-26 20:29:09
    **指应用执行一个操作所需的时间,包括从发出请求开始到最后收到响应所需要的时间**。拿我们平常浏览网站点击链接为例,响应时间大致包括如下几步: 1. 用户通过鼠标或键盘发出请求操作 2. 浏览器构造请求(请求头,...
  • JAVA多线程并发

    千次阅读 2022-02-17 14:41:51
    JAVA线程实现/创建方式 ...start()方法是一个native方法,它将启动一个新线程,并执行run()方法 public class MyThread extends Thread{ public void run(){ System.out.println("MyTread.r...
  • 讲一下并发和并行?

    千次阅读 2020-08-05 15:47:08
    并发是指两个或多个事件在同一时间线内间隔发生: 单核 cpu 下,线程实际还是串行执行的。操作系统中有一个组件叫做任务调度器,将 cpu 的时间片(windows下时间片最小约为 15 毫秒)分给不同的程序使用,只是...
  • Sql优化(三) 关于oracle的并发

    千次阅读 2021-05-04 09:40:07
    Oracle的并发技术可以将一个大任务分解为多个小任务由多个进程共同完成。合理地使用并发可以充分利用系统资源,提高效率。一、 并发的种类Parallel queryParallel DML(PDML)Parallel DDLParallel recovery[@more@]二...
  • 并发处理

    千次阅读 2019-12-30 13:13:47
    操作系统的特性之一是并发与共享,即在系统中(内存)同时存在几个相互独立的程序,这些程序在系统中既交叉地运行,又要共享系统中的资源,这就会引起一系列的问题,包括:对资源的竞争、运行程序之间的通信、程序...
  • 下面从程序的顺序执行、程序的执行环境和程序的并发执行几方面介绍多道程序设计模型。 一、程序的顺序执行 程序是一个在时间上按严格次序前后相继的操作序列,这些操作是机器指令或高级语言编写的语句。人们习惯的...
  • 某些类型的任务由专门的服务负责执行,且执行时间相对较长,因此需要对这些任务进行排队逐一处理。 此外,由于同种类型的两个任务之间可能需要按照先后顺序执行,因此还需要防止在集群环境下同一类型的多个任务出现...
  • 并发不是真正意义上的“同时进行”,只是CPU把一个时间段划分成几个时间片段(时间区间),然后在这几个时间区间之间来回切换,由于CPU处理的速度非常快,只要时间间隔处理得当,即可让用户感觉是多个应用程序同时在...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 316,326
精华内容 126,530
热门标签
关键字:

并发执行与时间有关的错误

友情链接: comTest.zip