如果我在Windows(10)计算机上运行以下Java程序(为了完整起见,我在这里发布程序):
public class IdleServer {
public static void main(String[] args) throws IOException, InterruptedException {
ServerSocket serverSock = new ServerSocket(9090);
Socket sock = serverSock.accept();
while (true) Thread.sleep(1000);
}
}
然后我从Haskell连接到Java服务器:
readWithinNSecs :: IO ()
readWithinNSecs = withSocketsDo $ do
h <- connectTo "localhost" (PortNumber 9090)
hSetBuffering h NoBuffering
readerTid <- forkIO $ reader h
threadDelay $ 2 * 10^6
putStrLn "Killing the reader"
killThread readerTid
putStrLn "Reader thread killed"
where
reader h = do
line <- strip <$> hGetLine h
putStrLn $ "Got " ++ line
然后当试图杀死试图从句柄读取的进程时,Haskell程序将挂起。杀死Java服务器将导致Haskell程序终止,同时给出错误:
<socket: 380>: hGetLine: failed (No error)
如果我在Linux上运行相同的两个程序,那么Haskell程序就会终止。
这似乎指向Haskell的base
库中的一个错误,所以I reported it,但在此期间我需要找到一种方法来解决这个问题。有什么想法吗?
更新:我发布了以下解决方案,但效果并不理想:它会终止读者线程,但会泄漏资源。
import Control.Concurrent.Async
-- ...
readerAsync h = do
a <- async $ strip <$> hGetLine h
line <- wait a
putStrLn $ "Got " ++ line