我将尝试使用 Haskell 创建一个简单的服务器。当客户端连接到服务器时,服务器会记录其地址。每隔n微秒,服务器发送一次广播。
以下是服务器代码:
服务器使用其线程并派生出另一个线程。派生的线程处理任何传入的客户端请求。
我遇到的问题是屏幕上从未打印出“2”。我认为这是因为
以下是服务器代码:
data Server = Server {
sSocket :: Socket,
sPort :: Port,
sClients :: MVar [ClientAddress]
}
注意MVar的使用,它允许客户端在多线程中使用。
这是创建服务器的方式
startServer port = withSocketsDo $ do
socket <- listenOn $ PortNumber $ fromIntegral port
clients <- newEmptyMVar
let server = Server socket port clients
forkIO $ forever $ accept socket >>= forkIO . (handleClientRequest server)
forever $ updateClients server 1000000
服务器使用其线程并派生出另一个线程。派生的线程处理任何传入的客户端请求。
handleClientRequest server client = do
clients <- takeMVar $ sClients server
putMVar (sClients server) (client : clients)
广播使用 updateClients
函数发送。
updateClients server frequency = do
putStrLn "1"
clients <- (takeMVar $ sClients server)
putStrLn "2"
putStrLn $ show $ length clients
threadDelay frequency
我遇到的问题是屏幕上从未打印出“2”。我认为这是因为
updateClients
中的takeMVar
行永远不会完成。为什么会冻结呢?
newMVar []
替代newEmptyMVar
,因为您从空的MVar开始,所以takeMVar
将永远阻塞。此外,如果可以使用withMVar
而不是takeMVar/putMVar
,那通常更好,因为如果出现异步异常,它会使MVar处于一致状态。 - John L