如何在Haskell中获取已创建进程的进程ID?

时间:2014-12-09 20:22:07

标签: haskell

也许我只是缺少System.Process API(http://hackage.haskell.org/package/process)中显而易见的东西,但它似乎不支持获取创建的进程的原始PID。 API通常会返回一个可以很容易使用的ProcessHandle,但这似乎不能满足我的部署需求。

我有一个案例,我想要生成一个长时间运行的进程,记录它正在使用的PID,并能够在以后的某个时间(几天,几周,几个月)自动返回并杀死旧进程并重新启动从一个新的过程开始。我确信有几种方法可以实现自动部署和重启,但PID似乎是最简单的方法,没有太多依赖于平台的代码。

我对其他基本问题的建议持开放态度,但对我来说似乎很奇怪,我在流程API中找不到任何直接PID引用(或转换为它们的方法)。这似乎是对API的疏忽。

3 个答案:

答案 0 :(得分:4)

以下是一些示例代码:

import System.Process
import System.Process.Internals

-- | returns Just pid or Nothing if process has already exited
getPid ph = withProcessHandle ph go
  where
    go ph_ = case ph_ of
               OpenHandle x   -> return $ Just x
               ClosedHandle _ -> return Nothing

main = do
  (_,_,_,ph) <- createProcess $ shell "echo $$"
  getPid ph >>= print

注意:我没有在Windows下对此进行测试,但它适用于OSX,可能是Linux。

对于Windows,Win32 package在模块getProcessId中有一个System.Win32.Process函数,根据我读过的代码,这应该有效:

import System.Win32.Process (getProcessId)

main = do
    (_,_,_,ph) <- createProcess $ shell "echo $$"
    pid <- withProcessHandle ph go
    print pid

  where go (OpenHandle x)   = fmap Just $ getProcessId x 
        go (ClosedHandle _) = return Nothing

我所依据的代码是interruptProcessGroupOf (link)

的代码

答案 1 :(得分:3)

interruptProcessGroupOf中的System.Process看起来System.Posix.Process.getProcessGroupIDOf(POSIX /非Windows)或System.Win32.Process.getProcessId(Windows)来获取pid:http://git.haskell.org/packages/process.git/blob/HEAD:/System/Process.hs

答案 2 :(得分:0)

如果其他一切都失败了,

import System.Process.Internals

然后深入挖掘ProcessHandle抽象。您可能希望从PHANDLE中提取MVar

请注意,这会破坏抽象层,这意味着可以使代码在操作系统之间移植。小心使用它,并准备好在新版本的库中打破它。