我正在开发一个 Ruby 脚本,它将向各种 API 发出数百个网络请求(通过 open-uri
),并且我想并行执行此操作,因为每个请求都很慢,并阻止。
我一直在考虑使用Thread
或Process
来实现这一点,但我不确定使用哪种方法。
关于网络请求,我什么时候应该使用Thread
而不是Process
,还是不重要?
最佳答案
在详细介绍之前,已经有一个库可以解决您的问题。 <强> Typhoeus 针对并行运行大量 HTTP 请求进行了优化,并且基于 libcurl 库。
Like a modern code version of the mythical beast with 100 serpent heads, Typhoeus runs HTTP requests in parallel while cleanly encapsulating handling logic.
线程将在与您的应用程序相同的进程中运行。自 Ruby 1.9 起,使用 native 线程作为底层实现。资源可以轻松地跨线程共享,因为它们都可以访问应用程序的相互状态。然而,问题在于大多数 Ruby 实现都无法利用 CPU 的多个内核。
Ruby 使用全局解释器锁 (GIL)。 GIL 是一种锁定机制,可确保相互状态不会因不同线程的并行修改而被破坏。其他 Ruby 实现(例如 JRuby、Rubinius 或 MacRuby)提供了一种无需 GIL 的方法。
进程彼此独立运行。进程不共享资源,这意味着每个进程都有自己的状态。如果您想在请求之间共享数据,这可能是一个问题。进程还分配自己的内存堆栈。您仍然可以使用 RabitMQ 等消息总线来共享数据。
我不建议仅使用线程或仅使用进程。如果您想自己实现,则应该同时使用两者。每 n 个请求就 fork 一个新进程,然后该进程再次生成许多线程来发出 HTTP 请求。为什么?
如果为每个 HTTP 请求创建另一个进程,这将导致进程过多。尽管您的操作系统可能能够处理此问题,但开销仍然是巨大的。有些 HTTP 请求可能会很快完成,所以为什么要费心去处理额外的进程,只需在另一个线程中运行它们即可。
关于ruby - 发出网络请求时,什么时候应该使用线程与进程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18216035/