Haskell 写入命名管道意外失败,并显示“openFile: 不存在(没有此类设备或地址)”

问题描述 投票:0回答:1

如果我使用

mkfifo /tmp2/example
创建了一个命名管道并使用以下函数:

writeToFifo :: FilePath -> IO ()
writeToFifo path = do
  handle <- openFile path WriteMode
  let loop n = do
        let msg = "Message " ++ show n
        hPutStrLn handle msg
        hFlush handle
        putStrLn $ "Wrote: " ++ msg
        threadDelay 1000000  -- Sleep for 1 second
        loop (n + 1)
  loop (1 :: Int)

但这会导致

* Exception: /tmp2/example: openFile: does not exist (No such device or address)

即使它存在

ls -alrth /tmp2/example
prw------- 1 chris users 0 Mar 30 12:54 /tmp2/example

为什么会出现这种情况?我该如何解决它?

haskell
1个回答
0
投票

这是由于

openFile
是通过文件阻塞实现的,如此处所述https://gitlab.haskell.org/ghc/ghc/-/issues/15715.

可以通过以下方式修复:

import GHC.IO.Handle.FD (openFileBlocking)

并将

openFile
替换为
openFileBlocking

或者:


writeToFifo :: FilePath -> IO ()
writeToFifo path = do
  -- Open the FIFO for writing, without creating it (assumes it exists)
  fd <- openFd path WriteOnly Nothing defaultFileFlags
  handle <- fdToHandle fd
  let loop n = do
        let msg = "Message " ++ show n
        hPutStrLn handle msg
        hFlush handle
        putStrLn $ "Wrote: " ++ msg
        threadDelay 1000000  -- Sleep for 1 second
        loop (n + 1)
  loop (1 :: Int)
© www.soinside.com 2019 - 2024. All rights reserved.