【发布时间】:2013-03-03 22:25:11
【问题描述】:
在Real World Haskell, Chapter 28, Software transactional memory 中,开发了一个并发的网络链接检查器。它获取网页中的所有链接,并用 HEAD 请求点击它们中的每一个,以确定链接是否处于活动状态。本程序采用并发的方式构建,声明如下:
我们不能简单地为每个 URL 创建一个线程,因为如果(如我们所料)大多数链接都是实时且响应式的,这可能会使我们的 CPU 或网络连接负担过重。相反,我们使用固定数量的工作线程,这些线程从队列中获取要下载的 URL。
我不完全理解为什么需要这个线程池而不是为每个链接使用forkIO。 AFAIK,Haskell 运行时维护一个线程池并适当地安排它们,所以我看不到 CPU 过载。此外,在a discussion about concurrency on the Haskell mailing list 中,我发现以下语句朝着相同的方向发展:
在 Haskell 中没有意义的一个范例是工作线程(因为 RTS 就是这样做的 为了我们);而不是获取一个工人,而只是 forkIO。
线程池是仅网络部分需要还是有 CPU 原因?
【问题讨论】:
-
需要池来控制并发级别并对其进行管理。您可能忘记了实际考虑因素。Haskell 运行时确实非常擅长维护 Haskell 空间线程 - 它们非常轻量级,您可以毫无问题地生成数千个线程。但是,当您获取 10 万个 url 的列表并且一个接一个地 forkIO 没有“池”时会发生什么?您可能会建立成千上万的连接。许多会超时,您的系统将用完文件描述符,并且您可能会在尝试处理结果时用完 RAM。