multithreading - 回调如何在非阻塞设计中工作?

标签 multithreading scala asynchronous callback nonblocking

看了一些其他问题,但没有完全找到我想要的。我使用 Scala,但我的问题非常高,因此希望对任何语言都不可知。

常规场景:

  • Thread A运行一个函数,并且有一些阻塞工作需要完成(比如一个 DB 调用)。
  • 该函数有一些非阻塞代码(例如 Scala 中的 Async 块)导致某种“ worker ”Thread B (在不同的池中)拿起 I/O 任务。
  • Thread A中的方法完成返回一个 Future ,最终将包含结果和 Thread A返回到其池中以快速接收另一个要处理的请求。

  • 一季度。某处的某个线程通常需要等待?

    我对非阻塞架构的理解是,常见的方法是在某处的 I/O 工作上仍然有一些线程等待/阻塞 - 这只是具有可以访问不同内核的不同池的情况,以便少量请求处理线程可以管理大量并发请求,而无需等待 CPU 内核。

    这是正确的一般理解吗?

    Q2。回调如何工作?

    在上述场景中 - Thread B如果/当 I/O 工作完成时,执行 I/O 工作的将运行回调函数(由线程 A 提供) - 这完成了 Future有一些结果。

    线程 A 现在正在做其他事情,并且不再与原始请求关联。 future 的结果如何发送回客户端套接字?我知道不同的语言对这种机制有不同的实现,但在高层次上,我目前的假设是(无论语言/框架如何)某些框架/容器对象必须始终进行某种编排,以便在 Future 任务是完成 Result 被发送回处理请求的原始套接字。

    我花了几个小时试图找到可以解释这一点的文章,但每篇文章似乎都只处理真正的低级细节。我知道我遗漏了一些细节,但我很难问我的问题,因为我不太确定我遗漏了哪些部分:)

    最佳答案

    My understanding of non-blocking architectures is that the common approach is to still have some Thread waiting/blocking on the I/O work somewhere



    如果一个线程在某处被阻塞,它就不是一个真正的非阻塞架构。所以不,这并不是对它的正确理解。这并不意味着这一定是坏事。有时您只需要处理阻塞(例如,使用 JDBC)。最好将其推送到指定用于阻塞的固定线程池中,而不是让整个应用程序遭受线程饥饿。

    Thread A is now off doing something else and has no association any more with the original request. How does the Result in the Future get sent back to the client socket?



    使用 Future s,这真的取决于ExecutionContext .当您创建 Future ,工作在哪里完成取决于 ExecutionContext .
    val f: Future[?] = ???
    val g: Future[?] = ???
    
    fg立即创建,工作被提交到 ExecutionContext 中的任务队列中.在大多数情况下,我们无法保证哪个将实际执行或首先完成。你如何处理这些值(value)观很重要。显然,如果您使用 Await等待完成Future s,然后我们阻塞当前线程。如果我们map他们并用这些值做一些事情,然后我们又需要另一个 ExecutionContext将任务提交给。这为我们提供了一系列任务,每次我们操作 Future 时,这些任务都会异步提交并重新提交给执行程序以执行。 .

    最终需要一些onComplete在该链的末尾将该值返回给某个东西,无论是写入流还是其他东西。即,它可能不在原始线程的手中。

    关于multithreading - 回调如何在非阻塞设计中工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29303457/

    相关文章:

    c++ - 多线程 SQLite 崩溃

    java - SwingUtilities InvokeLater-什么被认为是不好的做法?

    c - 进程的线程级内存消耗

    scala - 如何使用不可变的数据类型实现DFS

    scala - 为什么即使在未使用的情况下,我也会在 Heroku 上收到内存配额超出错误? (play2/scala)

    scala - 可以重命名基类中的 Scala 方法吗?

    python - Python中如何控制对多个底层对象的异步访问?

    c# - 自定义异步 HTTP 处理程序仅在 IIS 7.5 集成模式下生成错误 500 - 为什么?

    c# - 如果缓冲区太小,是否可以防止异常?

    c++ - 如果我锁定变量,是否必须将复杂类型标记为 `volatile`?