使用Haskell的非阻塞IO

mma*_*oti 3 haskell nonblocking node.js continuation-passing

可能重复:
对Node.js的Haskell响应是什么?
如何在Haskell中观察多个文件/套接字变为可读/可写?

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

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

Phi*_* JF 19

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
Run Code Online (Sandbox Code Playgroud)

Control.Concurrent.Async对于期货图书馆来说,这可能正是您所期待的.Haskell永远不应该只关注数千个(普通)线程.我还没有编写过使用数百万个IO线程的代码,但我猜你唯一的问题就是内存相关.


Tho*_*son 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
Run Code Online (Sandbox Code Playgroud)

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

  • 线程代码与单线程事件驱动的非阻塞代码不同。(我知道nodejs内部使用了线程池,这不是重点)。您必须使用 MVar 在线程之间进行通信,这涉及同步和更大规模的事务。但是,对于事件,我知道如果我不调用任何需要回调的内容,则没有其他任何东西会修改程序状态。您的解决方案使用“wait”,它会阻塞,因此此类异步方法的任何调用者都需要放入单独的线程中才能继续:每个方法调用一个线程,不是吗? (2认同)