也许我只是缺少System.Process API(http://hackage.haskell.org/package/process)中显而易见的东西,但它似乎不支持获取创建的进程的原始PID。 API通常会返回一个可以很容易使用的ProcessHandle,但这似乎不能满足我的部署需求。
我有一个案例,我想要生成一个长时间运行的进程,记录它正在使用的PID,并能够在以后的某个时间(几天,几周,几个月)自动返回并杀死旧进程并重新启动从一个新的过程开始。我确信有几种方法可以实现自动部署和重启,但PID似乎是最简单的方法,没有太多依赖于平台的代码。
我对其他基本问题的建议持开放态度,但对我来说似乎很奇怪,我在流程API中找不到任何直接PID引用(或转换为它们的方法)。这似乎是对API的疏忽。
答案 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
。
请注意,这会破坏抽象层,这意味着可以使代码在操作系统之间移植。小心使用它,并准备好在新版本的库中打破它。