首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >项目织机:当使用虚拟线程时,是什么使性能更好?

项目织机:当使用虚拟线程时,是什么使性能更好?
EN

Stack Overflow用户
提问于 2020-08-12 06:02:58
回答 3查看 2.1K关注 0票数 26

为了给出一些背景,我已经跟踪织机项目已经有一段时间了。我读过织机的状态。我做过异步编程。

异步编程(由Java提供)在任务等待时将线程返回到线程池,并且它会花费很长的时间来不阻塞线程。这提供了很大的性能增益,我们现在可以处理更多的请求,因为它们不受OS线程数量的直接约束。但我们在这里失去的是背景。同一任务现在仅与一个线程关联。一旦我们将任务从线程中分离出来,所有的上下文都会丢失。异常跟踪不提供非常有用的信息,调试也很困难。

带有虚拟线程的Project将成为并发的单一单元。现在,您可以在单个虚拟线程上执行单个任务。

到目前为止,一切都很好,但文章接着说,关于织机项目:

一个简单的、同步的web服务器可以处理更多的请求,而不需要更多的硬件。

我不明白我们如何通过使用Project来获得异步API的性能好处?S确保不使任何线程处于空闲状态。那么,Project如何提高异步API:s的效率和性能呢?

编辑

让我重新表述一下这个问题.假设我们有一个http服务器,它接收请求并使用后台持久数据库执行一些crud操作。比如说,这个http服务器处理很多请求-100 K RPM。实现这一目标的两种方式:

  1. HTTP服务器有一个专门的线程池。当请求传入时,线程会将任务拖到DB,其中任务必须等待来自DB的响应。此时,线程返回到线程池并继续执行其他任务。当DB响应时,它再次由线程池中的某个线程处理,并返回一个HTTP响应。
  2. HTTP服务器只是为每个请求生成虚拟线程。如果存在IO,则虚拟线程只需等待任务完成。然后返回HTTP响应。基本上,虚拟线程不存在池业务。

在硬件和吞吐量保持不变的情况下,任何一个解决方案在响应时间或处理更多吞吐量方面会比其他解决方案更好吗?

我猜想,w.r.t的性能不会有任何不同。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2020-12-09 12:47:15

回答 by @talex”简洁地描述了这一点。加得更深。

Loom更多地是关于本机并发抽象的,它还可以帮助编写异步代码。考虑到它是VM级别的抽象,而不仅仅是代码级别(就像我们到目前为止对CompletableFuture等所做的那样),它允许一个人实现异步行为,但可以减少锅炉板。

有了织机,一个更强大的抽象就是救世主。我们已经多次看到这一点:如何使用语法糖进行抽象,使人有效地编写程序。是否是FunctionalInterfaces in JDK8,for-理解在Scala.

有了织机,就不需要链接多个CompletableFuture(节省资源)。但是,我们可以同步编写代码。当遇到每个阻塞操作(ReentrantLock、i/o、JDBC调用)时,虚拟线程就会被停放。由于这些线程都是重量轻的线程,所以上下文切换非常便宜,可以区别于内核线程。

当阻塞时,实际的载体线程(即运行虚拟线程的run-body )将被用于执行其他虚拟线程的运行。因此,有效地,载体线程不是闲置,而是执行一些其他工作.回来继续执行原来的虚拟线程,无论何时取消停放。就像线程池的工作原理一样。但是在这里,您有一个载波线程,以一种方式执行多个虚拟线程的主体,在阻塞时从一个切换到另一个。

我们得到了与手工编写的异步代码相同的行为(以及相应的性能),但是却避免了用锅炉板来做同样的事情。

考虑一下web框架的情况,其中有一个单独的线程池来处理i/o,另一个用于执行http请求。对于简单的HTTP请求,可以从http池线程本身为请求提供服务。但是,如果存在任何阻塞(或)高CPU操作,则允许此活动异步地发生在单独的线程上。

该线程将收集来自传入请求的信息,生成一个CompletableFuture,并使用管道将其链接起来(从数据库读取作为一个阶段,然后从它进行计算,然后再从另一个阶段将其写回数据库案例、web服务调用等)。每个阶段都是一个阶段,并将得到的CompletablFuture返回到web框架。

当所得到的未来完成时,web框架使用将传递给客户端的结果。这就是Play-Framework和其他人一直在处理的问题。在http线程处理池和每个请求的执行之间提供隔离。但是如果我们深入研究这个问题,,为什么我们要这么做呢?

一个核心原因是资源的有效利用。尤其是阻塞电话。因此,我们使用thenApply等进行链接,这样就不会在任何活动上阻塞线程,并且我们用较少的线程来做更多的事情。

这很好,但是非常冗长的。调试确实是痛苦的,如果中间阶段中的某个阶段出现异常,控制流就会失控,从而产生更多的代码来处理它。

使用Loom,我们编写同步代码,并让其他人决定当阻塞时该做什么。而不是睡觉什么都不做。

票数 8
EN

Stack Overflow用户

发布于 2020-08-12 06:34:39

我们不能从异步API中获益。我们可能会获得与异步类似的性能,但使用同步代码。

票数 16
EN

Stack Overflow用户

发布于 2020-08-18 12:03:43

  1. http服务器有一个专门的线程池.有多大的游泳池?(CPU数)*N+ C?随着锁争用延长延迟,N>1可以退回到抗伸缩;在那里,N=1可以充分利用可用的带宽。有一个很好的分析这里
  2. http服务器刚刚产生..。这将是对这一概念的非常天真的执行。更现实的方法是从动态池中收集数据,动态池为每个阻塞的系统调用保留一个真正的线程+为每个真正的CPU保留一个线程。至少这就是幕后的人想出来的。

关键在于防止{处理程序、回调、完成、虚拟线程、goroutines :一个荚}中的所有PEA_s }不为内部资源而战斗;因此,它们不会依赖基于系统的阻塞机制,直到绝对必要时,这属于避免_lock的旗帜,并且可能通过各种队列策略(参见lib分派)来完成,等等。请注意,这使得PEA脱离了底层系统线程,因为它们在内部多路复用。这是你对离婚概念的关注。实际上,您传递的是您最喜欢的上下文指针的语言抽象。

正如1所指出的,有一些具体的结果可以直接与这种方法联系在一起;还有一些无形的东西。锁定是容易的--你只要在你的交易周围做一个大的锁,你就可以去了。这并不是规模,但细粒度的锁定是很难的。努力工作,努力选择谷物的细度。当使用{ locks、CVs、信号量、屏障、.}在教科书示例中是显而易见的;在深嵌套逻辑中则不那么明显。在大多数情况下,锁避免使其消失,并仅限于与之竞争的叶组件(如malloc() )。

我对此持怀疑态度,因为这项研究通常显示出一个规模不佳的系统,该系统被转换成一个锁避免模型,然后被证明更好。我还没有看到一个能释放出一些经验丰富的开发人员来分析系统的同步行为,将其转换为可伸缩性,然后度量结果。但是,即使这是一个胜利,经验丰富的开发人员是一种罕见的(Ish)和昂贵的商品;可伸缩性的核心实际上是金融。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63370669

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档