我已经推出了像这样的GHCi外部流程
(Just hin, Just hout, _, pid) <- createProcess (proc "ghci" ["-fdefer-type-errors"])
{ std_in = CreatePipe, std_out = CreatePipe, std_err = UseHandle stdout }
我通过写hin
并从hout
读取来控制。这用于将Haskell文件加载到外部GHCi进程中,调用其中一个函数,并读取其结果,这一切都有问题。
我的问题是有时会有一些函数在调用时无限运行,比如f n = sum [n..]
,当发生这种情况时,我想终止外部GHCi进程。
为此,我尝试调用函数terminateProcess pid
,但它不能可靠地终止进程;通常,外部进程停止工作,但在控制台上键入$ ps
时仍然会出现。例如,当ghc外部进程正在吃处理器时,这是顶部输出的示例:
PID COMMAND %CPU TIME ...
38312 top 3.3 00:00.89
38309 ghc 99.9 00:21.46
38306 ghc 0.0 00:00.82
当我尝试使用terminateProcess pid
结束它时,它通常会将进程降低到0%CPU,但仍然存在:
PID COMMAND %CPU TIME ...
38312 top 3.3 00:00.89
38309 ghc 0.0 00:21.46
38306 ghc 0.0 00:00.82
有时,我需要多次调用terminateProcess pid
来使外部ghc停止,但它总是在那里。即便如此,在它停止之后,当我尝试waitForProcess pid
时,这个阻止。
Haskell中是否有可靠的方法可以完全终止外部进程?像Unix kill -9 38309
一样吗?
由于
答案 0 :(得分:2)
在Posix系统上terminateProcess
只发送一个SIGTERM信号。
以下是一些代码,演示了如何将SIGKILL信号发送到使用System.Process
创建的Posix进程:
import System.Process
import System.Process.Internals
import System.Posix.Signals
main = do
(_, _, _, ph) <- createProcess (shell "asd")
-- ...
withProcessHandle ph $ \ph_ ->
case ph_ of
OpenHandle pid -> signalProcess sigKILL pid
ClosedHandle _ -> return () -- shouldn't happen