异步IO/反应式编程的目的

问题描述 投票:0回答:0

首先,问题所依据的一些假设:

同步IO: 当我需要进行读取IO操作时,我对文件描述符执行读取系统调用。 CPU 进入特权模式并执行内核代码,这(通过设备驱动程序)要求设备检索我的数据并将我的线程置于

BLOCKED
状态。最后,运行一个调度程序,另一个线程占用我的线程运行的 CPU 内核。
设备自行处理请求。完成后,它会触发 CPU 中断。中断处理程序执行内核代码,将我的线程状态设置为
READY
(这显然是一个很大的简化)。我的线程现在有机会在内核调度程序运行时被调度。

异步IO: 我执行系统调用,系统调用要求设备检索数据。现在,系统调用不设置线程状态,而是返回一个特殊标记以指示数据尚未准备好。线程继续执行。

我们通常不直接使用这样的系统调用,而是使用一些将回调作为参数的包装函数(由库提供)。该库还生成一个线程,该线程从所有调用(epoll、kqueue ...)中选择文件描述符。一旦某些 fds 可以与该线程交互,就会在某种工作线程线程池(运行事件循环/任务循环)上安排适当的回调。

如果上面的某些地方不对,我很乐意得到纠正!

现在,进入问题:

1。异步 IO 是否有任何性能/资源优势?
据我所知,与完整的上下文切换相比,线程之间的切换非常便宜。如果有足够的工作(将安排另一个线程),CPU 仍将得到充分利用。

以下是我能想到的:

  • 内存利用率——线程越少,内核代码中分配给堆栈和线程相关数据结构的内存就越少。
  • 调度开销——我想内核调度线程可能相当复杂。

但是我认为还有一些事情可能会损害异步 IO 的性能:

  • 我们总共执行了更多的系统调用(一个用于请求操作,另一个用于等待结果)
  • 回调需要安排给工人
  • 执行回调时跳转到任意位置可能会弄乱缓存?

2。反应式编程/协同程序,进一步推进了这个想法(所有代码在工作线程上作为事件运行)是否有任何性能优势?

3。为什么我们实际上做反应式编程?

在我看来,响应式编程在本来应该是开发人员可以处理的抽象(进程和线程)之上构建了一个额外的抽象层,这带来了很多额外的复杂性。 有时这似乎是有道理的,例如,如果我们假设我们想要一个单独的 UI 线程。这样做的问题是,从我的角度来看,这种模式基本上是同步的另一种方法——我们只需启动一个获取 UI 锁的线程就可以完成同样的事情。

我只是看不出传统的并发方法是什么导致了反应式编程框架的创建。

我将非常感谢所有涉及此的解释和来源。

multithreading performance asynchronous reactive-programming scheduler
© www.soinside.com 2019 - 2024. All rights reserved.