保证在Haskell中终止外部进程

时间:2015-10-31 01:07:42

标签: haskell

我已经推出了像这样的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一样吗?

由于

1 个答案:

答案 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