13

使用 Haskell Handles 时我感到有点不安全。也就是说,我正在寻找两个功能(也许它们已经存在,在这种情况下,请原谅我的无知)。

  1. 当我获得一个Network.accept可读可写的句柄(例如,返回)时,我希望将它们转换为一对 只读和只句柄,这样就不会写入只读句柄类型检查,反之亦然。(也许可以使用幻像类型并包装 IO 函数来实现这一点?)
  2. 在并发设置中,我发现多个线程可能会写入同一个句柄,这会产生非常糟糕的后果。如何通过类型系统(如果可能)防止这种情况发生,或者至少在运行时通过抛出的异常得到通知?

欢迎任何想法。

4

2 回答 2

8

看起来更安全的文件句柄库可以满足您的需求。第一部分处理得很清楚。并发安全似乎由RegionT区域处理。我根本没有使用过这个,但它看起来是一种很常见的方法。

于 2013-08-08T21:26:55.710 回答
2

您可能需要考虑使用网络导管包。它将网络应用程序描述为具有两个“端点”的东西 - 一个接收器将数据推送到套接字中,一个从套接字读取数据的源:

type Application m = AppData m -> m ()

data AppData m Source -- ...
appSource :: AppData m -> Source m ByteStringSource
appSink :: AppData m -> Sink ByteString m ()

这清楚地分开了写作和阅读部分。现在,您可以使用这样的源和接收器做任何您喜欢的事情,甚至将每个传递到不同的线程并分别处理输入和输出。当然,它们中的每一个都只能读或写,这取决于你给它的端点。

如果您想强制执行单线程处理,您可以限制自己将程序组件实现为Conduit ByteString m ByteString. 这样的管道可以很容易地变成Application类似的

asApp :: MonadIO m => Conduit ByteString m ByteString -> Application m
asApp cond ad = appSource ad $= cond $$ appSink ad

但是管道只能使用 请求数据await和写入输出yield,否则无法访问任何类型的句柄并且永远不会看到它的任何端点,因此它不能在任何地方暴露或泄漏它们。

于 2013-08-16T12:42:24.523 回答