Haskell 具有ProcessWait_uu和getExitCode竞争条件的类型化进程?

Haskell 具有ProcessWait_uu和getExitCode竞争条件的类型化进程?,haskell,process,typed-process,Haskell,Process,Typed Process,对于退出代码,上面的代码大多返回Nothing,而其他时候它将返回Just ExitSuccess,因此看起来是随机/竞争条件 为什么会发生这种情况 有关职能是: 我对函数的理解是,运行进程,等待它终止,然后运行IO a。然而我刚刚注意到有一个readProcess函数,它听起来像是我实际上应该使用的 尽管如此,了解上述/中使用ProcessWait时实际发生的情况还是很有用的。争用条件是三个单独的线程正在消耗所有可用的标准输出(第一个线程)和标准错误(第二个线程),并等待退出代码(第三个线程

对于退出代码,上面的代码大多返回
Nothing
,而其他时候它将返回
Just ExitSuccess
,因此看起来是随机/竞争条件

为什么会发生这种情况

有关职能是:


我对函数的理解是,运行进程,等待它终止,然后运行
IO a
。然而我刚刚注意到有一个
readProcess
函数,它听起来像是我实际上应该使用的


尽管如此,了解上述/
中使用ProcessWait时实际发生的情况还是很有用的。争用条件是三个单独的线程正在消耗所有可用的标准输出(第一个线程)和标准错误(第二个线程),并等待退出代码(第三个线程)。标准输出和标准错误线程可以在第三个线程发布退出代码之前完成完整输出并将其发布到STM

由于
getExitCode
检查退出代码TMVar但不等待,因此退出代码可能不可用。(事实上,如果子进程在退出之前关闭了标准输出并出错,那么此时它可能仍在运行!)

如果将
getExitCode
替换为
waitExitCode
,则可以可靠地获得
ExitAccess
。当然,
withProcessWait\uu
已经在等待退出代码,如果它不是
ExitSuccess
,则会引发异常,因此没有特别的理由这样做

import System.Process.Typed
import Control.Monad.STM
import Control.Concurrent.STM.TVar

processConf = setStderr byteStringOutput . setStdout byteStringOutput

main :: IO ()
main = do
  withProcessWait_ (processConf $ proc "sleep" ["1"])
          $ \p -> do
            atomically (getStdout p) >>= print
            atomically (getStderr p) >>= print
            getExitCode p >>= print
  print "test"
withProcessWait_ :: MonadUnliftIO m => ProcessConfig stdin stdout stderr -> (Process stdin stdout stderr -> m a) -> m a