Multithreading 为什么haskell.org上的聊天服务器示例是线程安全的?

Multithreading 为什么haskell.org上的聊天服务器示例是线程安全的?,multithreading,haskell,io,thread-safety,Multithreading,Haskell,Io,Thread Safety,我是Haskell的新手,我不知道我对Haskell wiki上的这个示例有什么不了解: 所讨论的具体代码如下: runConn :: (Socket, SockAddr) -> Chan Msg -> -> IO () runConn (sock, _) chan = do let broadcast msg = writeChan chan msg hdl <- socketToHandle sock ReadWriteMode hSetBuf

我是Haskell的新手,我不知道我对Haskell wiki上的这个示例有什么不了解:

所讨论的具体代码如下:

runConn :: (Socket, SockAddr) -> Chan Msg -> -> IO ()
runConn (sock, _) chan = do
    let broadcast msg = writeChan chan msg
    hdl <- socketToHandle sock ReadWriteMode
    hSetBuffering hdl NoBuffering
    chan' <- dupChan chan
    -- fork off thread for reading from the duplicated channel
    forkIO $ fix $ \loop -> do
        line <- readChan chan'
        hPutStrLn hdl line
        loop
    -- read lines from socket and echo them back to the user
    fix $ \loop -> do
        line <- liftM init (hGetLine hdl) 
        broadcast line
        loop
runConn::(Socket,SockAddr)->Chan Msg->->IO()
runConn(sock,uu)chan=do
让广播消息=写陈消息
hdl-do

line如果不安全,阻塞插座几乎不可能使用。如果您的协议是异步的,并且您使用的是阻塞套接字,那么几乎所有时间都需要线程阻塞读取。如果你需要向对方发送信息,你怎么能做到?等待另一方向您发送消息?

这并不是因为
forkIO
的性质,而是用于实现
Chan
Handle
MVar
的性质

如果你想了解
Chan
是如何工作的,可以看看西蒙·马洛(Simon Marlow)优秀著作第7章中的这一部分。在同一章中,有一节介绍如何以线程安全的方式实现
Handle


具体讨论了实现网络服务器的各种方法,包括使用STM而不是
Chan
s实现的聊天服务器。

我不确定
MVar
s在
Handle
的实现中到底防止了什么样的不良行为,但您可以假设haskell中的所有内容都是“线程安全的”,即“如果我在并发代码中使用它,就不会崩溃”。上述代码的一个变体,我们可能称之为haskelly意义上的非“线程安全”可能是,如果您使用
forkIO
-ed两个线程,这两个线程都从chan接收并回显它;在这种情况下,字符可以交错,例如“hellhelo lo worldworld”,感谢您提供有用的参考资料。我是否应该假设“基本”包中的所有(非纯)API都可以安全地并发访问?或者我应该养成检查源代码是否使用
MVar
s的习惯?