问题
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