我想创建一个进程并定期将我的haskell程序中的一些文本写入进程的stdin(来自IO操作) .
以下在GHCi中正常工作,但在构建和运行时无法正常工作 . 在GHCi中,一切都运行良好,IO动作的 Value 定期提供 . 然而,当构建并运行时,它似乎在写入进程的标准输入时暂停任意长时间 .
我已经使用 CreateProcess
(来自 System.Process
)来创建句柄并尝试 hPutStrLn
(bufferent设置为 NoBuffering
- LineBuffering
也没有工作) .
所以我正在尝试 process-streaming
包和 pipes
但似乎无法完成任何工作 .
真正的问题是:我如何从haskell创建一个进程并定期写入它?
展示此行为的最小示例:
import System.Process
import Data.IORef
import qualified Data.Text as T -- from the text package
import qualified Data.Text.IO as TIO
import Control.Concurrent.Timer -- from the timers package
import Control.Concurrent.Suspend -- from the suspend package
main = do
(Just hin, _,_,_) <- createProcess_ "bgProcess" $
(System.Process.proc "grep" ["10"]) { std_in = CreatePipe }
ref <- newIORef 0 :: IO (IORef Int)
flip repeatedTimer (msDelay 1000) $ do
x <- atomicModifyIORef' ref $ \x -> (x + 1, x)
hSetBuffering hin NoBuffering
TIO.hPutStrLn hin $ T.pack $ show x
任何帮助将不胜感激 .
2 回答
这是一个管道
Producer
,它发出一系列带有第二个延迟的数字:并且,使用process-streaming,我们可以将 生产环境 者提供给外部流程,如下所示:
我使用了executeInteractive,它将
std_in
自动设置为NoBuffering
.此外,如果您管道
std_out
并希望立即处理每个匹配项,请确保将--line-buffered
选项传递给grep(或使用stdbuf命令)以确保在输出中立即可以使用匹配项 .那么使用
threadDelay
,例如:如果您需要同时执行其他工作,请在另一个线程中生成此项 .
您可以通过以下方式删除他对IORef的需求:
当然,你只需要做一次
hSetBuffering
,例如在你进入循环之前做这件事 .