В Linux, как начать процесс, в своей группе процесс? и еще

я хотел бы начать процесс в своей собственной группе процессов (или, альтернативно, изменить свою группу после запуска) и:

  • пусть процессы в группе ответят на Ctrl + C из терминала
  • получите идентификатор группы процессов, чтобы я мог завершить все процессы в группе через .

Примечание: я пробовал setsid prog [args] но процессы не отвечают на Ctrl+C от терминала, и я не мог получить новый идентификатор группы процессов.

я также попытался изменить группу процессов через Perl setpgrp($pid, $pid) и POSIX::setpgid($pid, $pid), но безрезультатно.

Edit: большая проблема:

у меня есть процесс (однопоточный; назовем его "плодовитым" процесс P), который запускает многие дочерние процессы синхронно (один за другим; он начинает новый, когда предыдущий дочерний процесс завершается). Из терминала я хочу иметь возможность убивать P и дерево процессы под ним. Для этого я мог бы просто организовать убийство процессов в PС группы. Однако поведение по умолчанию-это P находится в группе родительского процесса. Это значит, что Pродитель будет убит, если я убью все процессы в Pгруппа, если у меня нет P и дерево в своей группе.

мое намерение убить P и дерево под ним, а не P'родители. Кроме того, я не могу изменить Pсам код.

3 ответов


что значит "запустить процесс в собственной группе процессов"? Оболочка запускает процессы в своих группах процессов, вот как она выполняет управление заданиями (имея группу процессов для процессов на переднем плане и несколько групп процессов для каждого конвейера, запущенного в фоновом режиме).

чтобы увидеть, что оболочка запускает новую группу процессов для каждого трубопровода, можно сделать так:

ps fax -o pid,pgid,cmd | less

что покажет что-то вроде:

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

обратите внимание, что оболочка создала новую группу процессов для конвейера, и каждый процесс в конвейере разделяет группу процессов.

Edit:

думаю, я знаю, к чему вы клоните. Ты зовешь system С Perl. Видимо, sh -c не создает новые группы процессов, так как это оболочка без управления заданиями.

что я бы сделал fork, затем на ребенка:

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

и wait на родителя.


EDIT: если вы хотели использовать setsid, но найти идентификатор сеанса и / или pid результирующего процесса:

Если вы запускаете процесс с помощью команды setsid, он не будет прикреплен к вашему терминалу, поэтому, конечно, он не будет отвечать на ctrl-C.

вы можете найти его, grepping через выход

ps x -O sid 

или что-то более ограниченное, как

ps x -o %c,%p,sid

или простой троллинг через proc / [pid] / stat для всех записей и просмотр идентификатор сеанса и все остальное, что представляет интерес (Подробнее см. man proc)

man-страница для setsid не дает никаких флагов для прямого генерирования вывода, но вы можете тривиально сделать свою собственную версию, которая печатает нужную информацию, изменив стандарт.

например, возьмите копию setsid.с одним из результатов

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

закомментировать nls включает, материал локали и макрос ошибки _ ( "" ), который вызовет проблемы, а затем добавит это прямо перед строкой execvp:

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

вот ответ в коде Perl после предложений ninjalj выше:

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}

}

еще раз большое спасибо!