gpt4 book ai didi

Haskell 在(理论上)不应该出现的情况下陷入僵局

转载 作者:行者123 更新时间:2023-12-04 03:54:24 26 4
gpt4 key购买 nike

以下产生死锁错误消息(* 异常:线程在 MVar 操作中无限期阻塞)。我一步一步想通了,没看出问题。

  • 在主线程上,创建一个 MVar,并将其提供给生产者,在新线程上运行
  • 生产者启动,并在 listenOn 处阻塞,等待连接
  • 主线程继续进入循环并阻塞,等待 MVar 接收
  • 一旦生产者获得连接,它就会继续进入它的循环,并在从套接字接收到一些东西后,将其放入 MVar

  • 意思是(据我所知),它最终应该是生产者在 MVar 中放入一些东西,而 main 等待接收一些东西。

    如果因为 listenOn 没有立即连接而卡住,我该如何解决这个问题? MVar 需要在 main 中创建,并且在生产者被 fork 之前,以便可以传入。
    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。

    使用 acceptlistenOn 之后等待远程连接应该可以解决这个问题。

    关于Haskell 在(理论上)不应该出现的情况下陷入僵局,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24976034/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com