Haskell在理论上不应该这样的情况下陷入僵局
以下内容会产生死锁错误消息(*异常:MVar操作中无限期阻塞的线程)。 我一直在想,它并没有看到这个问题。
意义(据我了解),它应该最终与生产者在MVar中放置一些东西,并主要等待接收一些东西。
如果因为listenOn没有立即连接而卡住了,我该如何解决这个问题? MVar需要在main中创建,并且在生成器被分离之前就可以传入。
import Control.Concurrent
import Network
import Network.Socket
import System.IO
getSockInfo :: Socket -> IO String
getSockInfo s = do
info <- getPeerName s
return $ case info of
(SockAddrInet port addr) -> "Addr/Port: " ++ (show addr) ++ " / " ++ (show port)
(SockAddrInet6 port flow addr scope) ->
"Addr/Port: " ++ (show addr) ++ " / " ++ (show port) ++ "Flow/Scope: " ++ (show flow) ++ " / " ++ (show scope)
producer :: MVar String -> IO ()
producer m = do
s <- listenOn (PortNumber 5555)
putStrLn "Listening..."
info <- getSockInfo s
putStrLn $ "Connected to " ++ info
h <- socketToHandle s ReadMode
loop h m
where loop h m = do
message <- hGetLine h
putMVar m message
loop h m
main :: IO ()
main = do
withSocketsDo $ do
m <- newEmptyMVar
prod <- forkIO $ producer m
loop m
where loop m = do
n <- takeMVar m
print n
loop m
listenOn
立即返回,但不会给你一个连接的套接字,所以试图使用它或从它读取失败。 我不知道为什么你没有看到一条错误消息来表明这一点,因为我在运行代码时会这样做。 在任何情况下,监听线程都可能在这一点上死亡,这导致主线程死锁,因为没有任何事情可以写入MVar。
在listenOn
之后使用accept
来等待远程连接应该解决这个问题。
上一篇: Haskell is getting deadlocked in a situation it (in theory) shouldn't be
下一篇: How to prevent ctrl+c killing spawned processes in Java