美文网首页互联网科技Java高级架构Java 杂谈
【本人秃顶程序员】异步编程:协作性多任务处理

【本人秃顶程序员】异步编程:协作性多任务处理

作者: 本人秃顶程序员 | 来源:发表于2019-03-05 20:57 被阅读5次

←←←←←←←←←←←← 快!点关注

如何确保同时处理多个请求,我们可以使用线程或进程进行多任务处理实现,但还有一个选择 - 协作性多任务处理。

这个选项是最困难的。在这里我们说操作系统当然很酷,它有调度程序/计划程序,它可以处理进程,线程,组织它们之间的切换,处理锁等,但它仍然不知道应用程序是如何工作的,而这些工作原理应该是我们作为开发人员所知道的。

我们知道在CPU上会有短暂的时刻执行某些计算操作,但大多数时候我们都期望网​​络I / O能更清楚何时在处理多个请求之间切换。

从操作系统的角度来看,协作式多任务只是一个执行线程,在其中,应用程序在处理多个请求/命令之间切换。通常情况是:只要一些数据到达,就会读取它们,解析请求,将数据发送到数据库,这是一个阻塞操作;而非堵塞操作时在等待来自数据库的响应时,可以开始处理另一个请求,它被称为“合作或协作”,因为所有任务/命令必须通过合作以使整个调度方案起作用。它们彼此交错,但是有一个控制线程,称为协作调度程序,其角色只是启动进程并让这些线程自动将控制权返回给它。

这比线程的多任务处理更简单,因为程序员总是知道当一个任务执行时,另一个任务不会执行,虽然在单处理器系统中,线程应用程序也将以交错模式执行这种模型,但使用线程的程序员仍应考虑此方法的缺陷,以免应用程序在移动到多处理器系统时工作不正常。但是,即使在多处理器系统上,单线程异步系统也总是以交错方式执行。

编写这样的程序的困难在于,这种切换,维护上下文的过程,将每个任务组织为一系列间歇性执行的较小步骤,落在开发人员身上。另一方面,我们获得了效率,因为没有不必要的切换,例如,在线程和进程之间切换时切换处理器上下文没有问题。

有两种方法可以实现协作式多任务处理 :回调和绿色线程。

回调

由于所有阻塞操作都会导致某个动作将在未来的某个时间发生,并且我们的执行线程应该在准备就绪时返回结果。因此,为了获得结果,我们必须注册回调 - 当请求/操作成功时,它将执行一个回调,或者如果它不成功,它将执行另一个回调。回调是一个明确的选项 - 开发人员应该以这样的方式编写程序,使他不知道何时将调用回调函数。

这是最常用的选项,因为它是显式的,并且得到了大多数现代语言的支持。

利弊

  • 与线程并发程序不同,没有线程并发的问题;
  • 线程/协同程序对程序员来说是不可见的;
  • 回调会吞掉异常;
  • 回调后的回调变得混乱,难以调试。

绿色线程

第二个选项是隐式的 ,当开发人员以这样的方式编写程序时,似乎不需要进行合作的多任务处理。我们就像之前一样做了一个阻塞操作,我们希望像只有一个进程或线程情况下获得结果。但是有一个黑魔法“在幕后” : 框架或编程语言使阻塞操作实现非阻塞,并将控制转移到其他一些执行线程,而不是转移到OS线程上,是在一个逻辑线程(用户 -级别线程)。它们由“普通”用户级进程调度,而不是由内核调度,这个线程称为绿色线程。

利弊

  • 是在应用程序级别而不是OS;
  • 他们感觉像线程;
  • 包括除CPU上下文切换之外的普通基于线程的编程的所有问题。

Reactor模式

在协作式多任务处理中,总有一个任务处理内核负责所有I / O处理。设计模式上称为Reactor模式。Reactor接口说:“给我一堆你的Socket和你的回调,当某个Socket准备好进行I / O时,我会调用你的回调函数。”

Reactor提供了第二个接口,称为定时器 - “在X毫秒内调用我,这是我需要你调用的回调。”

这种东西在任何地方都是协作式的多任务处理,无论是明确的还是隐含的。

“在引擎盖下”Reactor非常简单。它有一个按响应时间排序的计时器列表。它获取给出它的Socket列表,并将它们发送到轮询准备机制中。可用性轮询机制总是有一个参数: 它说明了如果没有网络活动他将堵塞多长时间。阻塞时间表示最近的计时器的响应时间。因此,要么存在某种网络活动,一些Socket将为I / O做好准备,或者我们将等待下一个定时器触发,解锁并将控制转移到一个或另一个回调,基本上是逻辑流程执行。

最好的方法

但实际上,这些选项都不是理想选择。合并后的版本效果最好,因为协作式多任务通常会带来好处,特别是如果您的连接挂起很长时间。例如,Web Socket是一种长期连接。如果分配一个进程或一个线程来处理单个Web Socket,则会显著地限制同时在一个后端服务器上可以拥有的连接数。由于连接存在很长时间,因此保持多个同时连接非常重要,而每个连接的工作量很少。

没有协作式多任务处理的程序只能使用一个处理器核心。当然,您可以在同一台机器上运行应用程序的多个实例(这并不总是方便且有其缺点),因此在每个进程内运行多个线程并使用reactor进行协同多任务处理会很不错。

这种组合一方面可以在我们的系统中使用所有可用的处理器内核,另一方面,它可以在每个内核中高效工作,而无需分配大量资源来处理每个单独的连接。

欢迎大家加入粉丝群:963944895,群内免费分享Spring框架、Mybatis框架SpringBoot框架、SpringMVC框架、SpringCloud微服务、Dubbo框架、Redis缓存、RabbitMq消息、JVM调优、Tomcat容器、MySQL数据库教学视频及架构学习思维导图

写在最后:

秃顶程序员的不易,看到这里,点了关注吧!
点关注,不迷路,持续更新!!!

如需Java架构资料,点关注,发简信给我即可,先到先得!

相关文章

  • 【本人秃顶程序员】异步编程:协作性多任务处理

    ←←←←←←←←←←←← 快!点关注 如何确保同时处理多个请求,我们可以使用线程或进程进行多任务处理实现,但还有一...

  • 重拾Java(4)-线程

    一、概述 Java对多线程编程提供了内置支持,多线程是特殊形式的多任务处理,所有现代系统都支持多任务处理。多任务处...

  • RxSwift学习

    编程思想 用同步的方式,编写处理异步事件的代码。是基于异步 Event(事件)序列的响应式编程。它可以简化异步编程...

  • 【本人秃顶程序员】Java并发编程—synchronized保证

    ←←←←←←←←←←←← 快!点关注 前言 程安全是并发编程中的重要关注点,应该注意到的是,造成线程安全问题的主要...

  • 【本人秃顶程序员】Java的SOLID编程原则

    ←←←←←←←←←←←← 快!点关注 SOLID阐述了五种设计原则,可帮助开发人员轻松扩展和维护软件: S - 单...

  • JS异步编程(一):单线程模型

    随着对JS的深入,异步编程是每个JS程序员都跳不过的话题。不仅在前端开发有大量的异步事件处理,NODE更是有出了名...

  • js回调与异步编程

    回调与异步编程 一、回调函数的使用场景 异步编程。 事件监听、处理。 setTimeout、setInterval...

  • ES6 之 Promise

    Promise是JavaScript异步编程中的重要概念,异步抽象处理对象,是目前比较流行Javascript异步...

  • 九:安全脆弱性、威胁和对策

    9.1 评估和缓解安全脆弱性 9.1 硬件 处理器 执行类型1:多任务处理: 同时处理两个或更多任务2:多处理: ...

  • JS异步编程(3)-Promise

    Promise 是 JS 异步编程中的重要概念,异步抽象处理对象,是目前比较流行的异步编程解决方案之一。主要解决了...

网友评论

    本文标题:【本人秃顶程序员】异步编程:协作性多任务处理

    本文链接:https://www.haomeiwen.com/subject/wylauqtx.html