[erlang-questions] How do you kill an OS process that was opened with open_port on a brutal_kill?
Fri Nov 25 21:48:20 CET 2016
On 11/25/2016 09:17 AM, Vans S wrote:
> Per Hedeland and José Valim that method works great. One small peeve is it makes an extra process but the only way around this would be to patch the OS Processes code to terminate when stdin closes. For now using the shell script is more then enough.
A well-behaved port should be checking the file descriptor to see if it is closed. I prefer to use the poll function and check revents on the file descriptor for the POLLHUP, since I know that if that is present, Erlang has exited. However, it is possible that the port execution takes a long time before actually getting to the poll function, so, it is nice to have a termination timeout on the Erlang side that uses os:cmd("kill -9 " ++ PID) to ensure the OS process actually dies at some point in time. Otherwise, it is possible to suspend the port and have it hanging around forever. If you use external services in CloudI, this is handled for you, which helps to avoid spending time on these details.
> On Friday, November 25, 2016 6:33 AM, Per Hedeland <per@REDACTED> wrote:
> On 2016-11-25 11:27, José Valim wrote:
>> If I remember correctly, the stdin of the program started with open_port will be closed when the Erlang VM terminates.
> Right - this is guaranteed by the OS kernel, which closes all open file
> descriptors for a process when it terminates. Should be true even for
> Windows with whatever is used to communicate with port programs there.
>> So if the OS process is listening to stdin and exiting when the stdin closes, you
>> don't need to worry about terminating it.
> Yes. And this is the *only* way to ensure that the port program *always*
> terminates when it should - it covers all of
> - port is explicitly closed
> - port-owning Erlang process terminates
> - Erlang VM terminates
> With Raimo's suggestion, the port program will continue to run if the
> Erlang VM terminates "abruptly" (e.g. killed by e.g. the OOM-killer, or
> failing to allocate memory). The design that stipulates that port
> programs should (attempt to) read stdin and terminate when they see EOF
> wasn't done on a whim...
>> When they don't do so, you can also write a script that spawns the OS process and traverses stdin until it closes and then it terminates the OS process when stdin closes. Something like:
>> $name $*
>> while read line ; do
>> done < /dev/stdin
>> kill -KILL $pid
>> If you save it as "wrap" then you can start your OS process as "wrap NAME ARGS". This can be handy if you cannot rely on C/C++ extensions. If anyone knows any drawback to such approach, I would love
>> to hear.
> Well, your script is missing a '&' on the "$name $*" line to make the
> "target" program run in the (script's) background, but otherwise it
> should be fine. I'd like to suggest a bit of simplification and
> increased portability though:
> "$@" &
> while read line ; do
> kill -KILL $pid
> (And you could of course using something "nicer" than -KILL, e.g. -TERM,
> if you are sure that it will be sufficient to terminate the program.)
> --Per Hedeland
> erlang-questions mailing list
> erlang-questions mailing list
More information about the erlang-questions