How to start a process in its own process group?

I would like to start a process in my own process group (or, conversely, change its group after start) and:

  • so that the processes in the group respond to Ctrl + C from the terminal
  • get the process group id so that I can terminate all the processes in the group with the kill command.

Note. I tried setsid prog [args] , but the processes did not respond to Ctrl + C from the terminal, and I could not get the new process group identifier.

I also tried changing the process group via Perl setpgrp($pid, $pid) and POSIX::setpgid($pid, $pid) , but to no avail.

Edit: big problem:

I have a process (single-threaded, call it the "prolific" process P ) that synchronously starts many child processes (one by one, it starts a new one when the previous child process ends). From the terminal I want to kill P and the process tree under it. To do this, I could simply settle the processes in group P However, the default behavior is that P is in the group of the parent process. This means that the parent of P will be killed if I kill all the processes in group P , if I do not have P , and his tree will be in their own group.

My intention is to kill P and the tree below it, but not P parent. Also, I cannot change the P code itself.

+7
source share
3 answers

What does it mean to “start a process in its own process group”? The shell starts processes in its process groups, since it performs job management (having a group of processes for processes in the foreground and several process groups for each pipeline running in the background).

To make sure that the shell starts a new process group for each pipeline, you can do this:

 ps fax -o pid,pgid,cmd | less 

which will show something like:

 11816 11816 | \_ /bin/bash 4759 4759 | \_ ps fax -o pid,pgid,cmd 4760 4759 | \_ less 

Notice that the shell has created a new process group for the pipeline, and each process in the pipeline shares a process group.

Edit:

I think I know what you're driving at. You call system from Perl. Apparently, sh -c does not create new process groups, since it is a shell without job control.

What I would do would be fork , and then on the child:

 setpgrp; system("ps fax -o pid,pgid,cmd"); 

and wait for the parent.

+3
source

EDIT: If you want to do this, use setid, but find the session id and / or pid of the resulting process:

If you start the process using the setsid command, it will not be attached to your terminal, therefore, of course, it will not respond to ctrl-c.

You can find it by grepping through output

 ps x -O sid 

or something more limited like

 ps x -o %c,%p,sid 

Or simple trolling through proc / [pid] / stat for all records and viewing the session identifier and any other interest (for more details see man proc)

The man page for setsid does not give any flags for direct output generation, but you can trivially create your own version that displays the necessary information by changing the standard.

For example, take a copy of setsid.c from one of the results for

http://www.google.com/codesearch?as_q=setsid&as_package=util-linux

Comment on nls include, the locale file, and the error macro _ (""), which will cause problems, and then add this right before the execvp line:

  printf("process will be pid %d sid %d\n", getpid(), getsid(0)); 
+1
source

Here is the answer in Perl code after the following ninjalj sentences:

prolific_wrapper.pl

 my $pid = fork(); if (not defined $pid) { die 'resources not available'; } elsif ($pid == 0) { # CHILD setpgrp; exit system(prolific => @ARGV); } else { # PARENT my $was_killed = 0; local $SIG{INT} = sub { say 'kill prolific and its tree ...'; kill KILL => -$pid; $was_killed = 1; }; wait; my $child_status = $?; $SIG{INT} = 'DEFAULT'; if ($was_killed) {kill INT => $$} else {exit $child_status} } 

Thanks again!

0
source

Source: https://habr.com/ru/post/886820/


All Articles