使用Haskell的非阻塞IO

时间:2012-12-10 23:34:09

标签: node.js haskell nonblocking continuation-passing

  

可能重复:
  What is the Haskell response to Node.js?
  How can I watch multiple files/socket to become readable/writable in Haskell?

是否有可能编写一个以非阻塞方式执行IO的Haskell程序,如nodejs?

例如,我想从远处的数据库中获取10条记录,因此我想同时发出10条请求,当结果可用时,则返回此集合。 IO monad不会提供帮助,因为monad使用bind显式序列化计算。我认为继续传递样式,你传递下一个你想要的计算具有相同的问题,再次它序列化计算。我不想使用线程,我正在寻找另一种解决方案。这可能吗?

2 个答案:

答案 0 :(得分:18)

Haskell线程非常轻。更重要的是,GHC IO monad在很多时候使用事件驱动的调度,这意味着普通的Haskell代码就像继续传递样式node.js代码(只编译为本机代码并运行多个CPU ...)

你的例子很简单

import Control.Concurrent.Async

--given a list of requests
requests :: [IO Foo]

--you can run them concurrently
getRequests :: IO [Foo]
getRequests = mapConcurrently id requests

Control.Concurrent.Async可能正是您正在寻找的关于期货库的内容。 Haskell永远不应该只关注数千个(普通)线程。我还没有编写过使用数百万个IO线程的代码,但我猜你唯一的问题就是内存相关。

答案 1 :(得分:8)

为了充实Control.Concurrent.Async上的评论,以下是使用async包的示例。

import Network.HTTP.Conduit
import Control.Concurrent.Async

main = do
    xs <- mapM (async . simpleHttp) [ "www.stackoverflow.com"
                                    , "www.lwn.net"
                                    , "www.reddit.com/r/linux_gaming"]
    [so,lwn,lg] <- mapM wait xs
    -- parse these how ever you'd like

因此,在上文中,我们为三个不同的网站定义了三个HTTP get请求,异步启动这些请求,并等待所有三个请求完成再继续。