How to get the process ID of a created process in Haskell?

十年热恋 提交于 2020-01-02 03:56:05

问题


Maybe I'm just missing something obvious in the System.Process API (http://hackage.haskell.org/package/process), but it doesn't appear to support getting the raw PID of a process created. The API usually returns a ProcessHandle which can be used easily enough, but this doesn't appear to fulfill a deployment need I have.

I have a case where I want to spawn a long-running process, log the PID it's using, and be able to automatically come back at a later time (days, weeks, months) and kill the old process and re-start with a new process. I'm sure there are several ways to do this auto-deploy-and-restart, but PIDs seemed like the simplest way to do so without too much platform-dependent code.

I'm open to other suggestions about my underlying problem, but it seems odd to me that I can't find any direct PID references (or a way to convert to them) in the process API. This seems like an oversight of the API.


回答1:


Here is some example code:

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

Note: I haven't tested this under Windows, but it works on OSX and, presumably, Linux.

For Windows, the Win32 package has a getProcessId function in the module System.Win32.Process, and according to code I've read, this should work:

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

The code I am basing this on is the code for interruptProcessGroupOf (link)




回答2:


Looks like interruptProcessGroupOf in System.Process calls either System.Posix.Process.getProcessGroupIDOf (POSIX/not Windows) or System.Win32.Process.getProcessId (Windows) to get the pid: http://git.haskell.org/packages/process.git/blob/HEAD:/System/Process.hs




回答3:


If everything else fails,

import System.Process.Internals

and then dig inside the ProcessHandle abstraction. You probably want to extract the PHANDLE from the MVar.

Note that this breaks the abstraction layer, which is meant to make the code portable across OSs. Use it with extreme care, and be prepared for it to break in new versions of the library.



来源:https://stackoverflow.com/questions/27388099/how-to-get-the-process-id-of-a-created-process-in-haskell

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!