Reputation: 28384
I am experimenting with System.Process
and Control.Concurrent.Async
for the purpose of spawning an external process, as well as threads to control its standard input and output.
However, while playing around with those libraries, I've managed to create a situation where 2 instances of my Haskell program communicate with each other (via the external socat
process), the threads of each program communicate via an MVar
to decide what to do, the two programs exit with 0, and yet... one of the two external socat
processes spawned via System.Process.createProcess
is left running, so I have to manually kill
it.
Sure, maybe the issue is with the program I wrote beside the usage of createProcess
, but to start with, I want to make sure I understand how createProgram
syhould be used.
So the question is: once I execute something like this
import System.Process
main :: IO ()
main = do
args <- getArgs
(Just i, Just o, Nothing, h) <- createProcess (proc "socat" args)
{std_in = CreatePipe, std_out = CreatePipe}
-- rest
who or what is responsible for putting down the process spawned by createProcess
?
After all, -- rest
executes immediately after the call to createProcess
, so while -- rest
executes, the shell program, in this case socat
is running on its own. Is it up to me to guarantee correct lifetime management? Should I make use of h
for this purpose?
One experiment is this:
import System.Process
main :: IO ()
main = do
_ <- createProcess (proc "cat" ["/dev/zero"])
{std_in = CreatePipe, std_out = CreatePipe}
return ()
Since cat /dev/zero
never returns (I've tried in the Bash shell), shouldn't this program terminate leaving cat
running? I.e., after the Haskell program terminates successfully, shouldn't pidof cat
return some PID?
I've tried, and it doesn't, making me think that something is cleaning up.
Upvotes: 0
Views: 27