我正在开发一个Haskell网络应用程序,并使用Actor模式管理多线程。我遇到的一个问题是如何存储客户端套接字/句柄集合,这些信息必须对所有线程都可访问,并且在客户端登录/退出时可能会更改。
由于我来自命令式编程世界,所以我想到了一种锁定机制,但当我意识到这种方法很丑陋时,我思考了“纯”可变性,实际上它有点纯净。
由于我来自命令式编程世界,所以我想到了一种锁定机制,但当我意识到这种方法很丑陋时,我思考了“纯”可变性,实际上它有点纯净。
import Control.Concurrent
import Control.Monad
import Network
import System.IO
import Data.List
import Data.Maybe
import System.Environment
import Control.Exception
newStorage :: (Eq a, Show a) => IO (Chan (String, Maybe (Chan [a]), Maybe a))
newStorage = do
q <- newChan
forkIO $ storage [] q
return q
newHandleStorage :: IO (Chan (String, Maybe (Chan [Handle]), Maybe Handle))
newHandleStorage = newStorage
storage :: (Eq a, Show a) => [a] -> Chan (String, Maybe (Chan [a]), Maybe a) -> IO ()
storage s q = do
let loop = (`storage` q)
(req, reply, d) <- readChan q
print ("processing " ++ show(d))
case req of
"add" -> loop ((fromJust d) : s)
"remove" -> loop (delete (fromJust d) s)
"get" -> do
writeChan (fromJust reply) s
loop s
store s d = writeChan s ("add", Nothing, Just d)
unstore s d = writeChan s ("remove", Nothing, Just d)
request s = do
chan <- newChan
writeChan s ("get", Just chan, Nothing)
readChan chan
重点是,一个线程(actor)管理着一组项目,并根据传入的请求修改该清单。由于线程非常便宜,我认为这可能是一种非常好的函数替代方法。
当然,这只是一个原型(快速的脏证明概念)。 所以我的问题是:
- 这是管理共享可变变量的“好”方法吗(在actor世界中)?
- 是否已经有了这种模式的库?(我已经搜索过了,但什么也没找到)
问候, Chris
Map
/Set
)或基于ST/IO
的哈希集合肯定会有所帮助。 - Petr