我正在使用包中的race
函数async
,导出Control.Concurrent.Async
.
我使用race
自己runInteractiveProcess
启动的子任务调用运行(非Haskell)可执行文件.我们的想法是运行不同的外部程序,并完成第一个程序的结果.从某种意义上说,Haskell"编排"了一堆外部程序.
我所观察到的是,race
通过杀死Haskell级别"慢"线程正常工作; 从慢线程本身产生的子进程继续运行.
我怀疑期望race
杀死以这种方式产生的进程有点不切实际,因为它们可能变成了僵尸并被init继承.然而,出于我的目的,保持外部进程运行首先失败了使用的全部目的race
.
是否有另一种使用方式,race
因此以这种方式创建的子进程也会被杀死?虽然我还没有用例,但最好是从race
d任务创建的整个流程链被杀死; 可以想象,那些外部程序本身也会创建一堆进程.
正如评论中已经提到的,您可以使用onException和terminateProcess的组合.
我的流程流库(包含基于流程和管道构建的辅助函数)已经实现了这一点.异步异常触发外部进程的终止.
例如,以下代码不会创建文件toolate.txt
.
import qualified Pipes.ByteString as B
import System.Process.Streaming
import Control.Concurrent.Async
main :: IO ()
main =
do
result <- race (runProgram prog1) (runProgram prog2)
putStrLn $ show $ result
where
-- collecting stdout and stderr as bytestrings
runProgram = simpleSafeExecute $ pipeoe $
separated (surely B.toLazyM) (surely B.toLazyM)
prog1 = shell "{ echo aaa ; sleep 2 ; }"
prog2 = shell "{ echo bbb ; sleep 7 ; touch toolate.txt ; }"
Run Code Online (Sandbox Code Playgroud)
结果是:
Left (Right ("aaa\n",""))
Run Code Online (Sandbox Code Playgroud)