htop icon indicating copy to clipboard operation
htop copied to clipboard

Add a 'kill process group' feature bound to the 'g' key

Open Arkanosis opened this issue 8 years ago • 11 comments

(Opening a new issue to replace the former #122 which looks buggy for some reason, but the content is exactly the same.)

Hello,

This PR adds the “kill group” feature bound to the “g” key. It works exactly as the “kill” feature (F9/k), except that it kills all processes sharing the same PGRP instead of a single process.

Best regards,

Arkanosis avatar Feb 11 '16 17:02 Arkanosis

I have a question: What is the use case for this? Killing all processes of a process group seems to be more dangerous than just killing one. And ideally you don't have to (most of the time) -- for a well written multi-threaded program, if a child (process or thread) dies, the parent should notice this and exit itself and its children properly. So I can't think of any use case that makes this useful. top doesn't implement such thing either.

Explorer09 avatar Feb 12 '16 11:02 Explorer09

I'm using this on a daily basis for about two years now… Use case: a script which spawns other processes but doesn't kill them when it gets killed itself. The only way I have to kill all these processes is either to kill each of them individually (since killing the parent has no effect but making init adopt them, thus making the whole picture even more confusing) or killing the whole process group, which is exactly what's needed here. I had been doing this for months using kill -PGRP, then I decided I could as well improve htop to do this.

Is it dangerous? Well, yes. But killing a process is already dangerous anyhow. That's the user responsibility to use it wisely. top has no such feature, but I'm precisely using htop because it has more features than top. kill has had that feature for as long as I can remember.

PS: In my specific case, there's no point for the parent to exit itself, since it's some kind of watchdog, spawning processes again when they happen to die (making it hopeless to kill children processes individually, by the way). The fact it's useful here isn't even relevant IMHO: one may have to deal with all kinds of programs (even badly written ones), and I'm glad htop usefulness is not limited to “well written program” (whichever definition of “well written” you might use).

Arkanosis avatar Feb 12 '16 12:02 Arkanosis

@Arkanosis That is what I'm questioning. Your script could be programmed to trap a signal, and after the signal it kills all children it watches. Letting htop do that will bring me at least one question: So in what order htop will send signals to the processes? Does it send signal to the parent first, or to the children first? That matters. Especially to programs that kills its own children like what I mentioned above. If it's not implemented carefully, race conditions could happen.

And I do have scripts that are coded to kill children when they catch SIGTERM (here if you are insterested). So I know the difficulty with this signals thing.

EDIT & UPDATE: In this killpg(2) documentation for POSIX, it's example uses killpg ( or kill(-pgrp, sig) as you say) only to kill its own group, and it's careful enough not to throw a signal to the sender process itself. And AFAIK the standard doesn't state the sending order.

Explorer09 avatar Feb 12 '16 13:02 Explorer09

It's not my script. It's a script I have to use. Changes to the programs are irrelevant here as one has to deal with whatever actually exists, not only what is “good” (for whichever definition of “good”).

As for the implementation concerns, there's no magic here: the kill system call do support killing a whole process group (I mean: processes sharing the same pgrp, not an arbitrary group of processes), so htop sends the signal to all the processes at the same time and the kernel cares. This is actually much safer than the tagging feature currently offered by htop (which it doesn't intend to replace, though, since its scope is much thinner).

To quote Eric W. Biederman on LKML: “When we send a signal to multiple processes it needs to be an atomic operation so that kill -KILL -pgrp won't let processes escape. It is what posix specifies, it is what real programs expect, and it is the useful semantic in userspace.

Thanks for the pointers, though. That's certainly good to know in other contexts.

Arkanosis avatar Feb 12 '16 14:02 Arkanosis

@Arkanosis I have to admit I was a bit off-topic in the last post. You're right, there's only one system call that we will concern, and race is not a matter for htop (but a matter for kernel). I was just trying to point out a danger of sending signals to multiple processes at once, and I didn't explain that very well. Back on topic.

Here is the summary of what I am concerned about the killing process groups feature now: (1) There are too few use cases (IMHO) to make this feature a necessary (although you may disagree). (2) Arkanosis's approach (the 'g' hotkey) to kill a process group is too easy to accidentally trigger. (3) I don't see any process monitor program (top or any GUI) has dared implement this. If htop is going to the first one to implement, then it has to be done very carefully.

For point (2), if I were going to have this feature, I would let user press the 'k' key first; after the signal selection menu shows up, press the dash/minus '-' key to enter the Process Group Killing Mode. The process list UI will reflect to this, and shows the processes in the group that would be killed, in red text, in order to give the user a sense of danger.

And for ultimate safety, PGID 1 would be prohibited from killing in htop no matter what. You know what behavior it is for kill(-1, sig), so that makes sense.

Explorer09 avatar Feb 12 '16 16:02 Explorer09

And here's the idea of what it would look like: (GIMP-edited. Not actual screenshot.) screenshot from 2016-02-13 00 32 58

Explorer09 avatar Feb 12 '16 16:02 Explorer09

What if changing g to tag all processes in the group/tree, then k to kill tagged processes as usual?

agguser avatar Jun 01 '18 12:06 agguser

Hi @agguser, thank you for the suggestion!

What if changing g to tag all processes in the group/tree, then k to kill tagged processes as usual?

You can already use the c key to tag all the children of a process; hitting k then loops over tagged processes to kill them.

Adding the ability to tag a process group instead of a tree might be useful, but the idea of actually killing a group rather than just tagging it was to make the killing operation atomic, which the tagging + looping over tagged processes combo is not (see my previous comment for a more technical explanation).

Arkanosis avatar Jun 01 '18 12:06 Arkanosis

Thanks for explaining. c key works, but why not in the man page?

agguser avatar Jun 01 '18 14:06 agguser

Indeed, c is missing from the man. I guess that's just an oversight. Good spot!

Arkanosis avatar Jun 01 '18 14:06 Arkanosis

@agguser: I've submitted another pull request for that: #796

Arkanosis avatar Jun 01 '18 15:06 Arkanosis