Интересный вопрос - не в последнюю очередь потому, что он так долго оставался без частичного ответа.
Базовые определения POSIX
Некоторые цитаты из части определений POSIX:
3.290 Группа процессов
Коллекция процессов, которая разрешает сигнализацию связанных процессов. Каждый процесс в системе является членом группы процессов, которая идентифицируется идентификатором группы процессов. Вновь созданный процесс присоединяется к группе процессов его создателя.
3.291 ID группы процессов
Уникальный положительный целочисленный идентификатор, представляющий группу процессов в течение ее жизненного цикла.
Примечание:
См. Также Повторное использование идентификатора группы процессов, определенное в разделе Повторное использование идентификатора процесса.
3.292 Руководитель группы процессов
Процесс, идентификатор процесса которого совпадает с идентификатором его группы процессов.
3.293 Время жизни группы процессов
Период времени, который начинается, когда создается группа процессов, и заканчивается, когда последний оставшийся процесс в группе покидает группу, из-за окончания времени жизни последнего процесса или последнего оставшегося процесса, вызывающего setsid () или setpgid ().
Примечание:
Функции setsid () и setpgid () подробно описаны в разделе «Системные интерфейсы» POSIX.1-2008.
[...]
3.337 Сессия
Набор групп процессов, созданных для контроля работы. Каждая группа процессов является членом сеанса. Процесс считается участником сеанса, членом которого является его группа процессов. Вновь созданный процесс присоединяется к сеансу своего создателя. Процесс может изменить свое членство в сеансе; см. setsid (). В одном сеансе может быть несколько групп процессов.
Примечание:
Функция setsid () подробно описана в разделе «Системные интерфейсы» POSIX.1-2008.
3.338 Лидер сессии
Процесс, который создал сеанс.
Примечание:
Для получения дополнительной информации см. Функцию setsid (), определенную в томе «Системные интерфейсы» POSIX.1-2008.
3.339 Время жизни сессии
Период между созданием сеанса и окончанием времени жизни всех групп процессов, которые остаются членами сеанса.
Системные интерфейсы POSIX
ИМЯ * * тысяча пятьдесят-одна
setsid - создать сеанс и установить идентификатор группы процессов
СИНТАКСИС
#include <unistd.h>
pid_t setsid(void);
* +1057 * ОПИСАНИЕ * * тысяча пятьдесят-восемь
Функция setsid () должна создать новый сеанс, если вызывающий процесс не является лидером группы процессов. По возвращении вызывающий процесс должен быть лидером сеанса этого нового сеанса, должен быть лидером группы процессов новой группы процессов и не должен иметь управляющего терминала. Идентификатор группы процессов вызывающего процесса должен быть установлен равным идентификатору процесса вызывающего процесса. Вызывающий процесс должен быть единственным процессом в новой группе процессов и единственным процессом в новом сеансе.
И
ИМЯ
setpgid - установить идентификатор группы процессов для управления заданиями
СИНТАКСИС
#include <unistd.h>
int setpgid(pid_t pid, pid_t pgid);
* 1 072 * ОПИСАНИЕ
Функция setpgid () должна либо присоединиться к существующей группе процессов, либо создать новую группу процессов в сеансе вызывающего процесса.
Идентификатор группы процессов лидера сеанса не должен изменяться.
После успешного завершения идентификатор группы процессов для процесса с идентификатором процесса, который соответствует pid, должен быть установлен в pgid.
В особом случае, если pid равен 0, должен использоваться идентификатор процесса вызывающего процесса. Также, если pgid равно 0, должен использоваться идентификатор процесса указанного процесса.
Интерпретация
Как ясно из определений, сеанс может состоять из нескольких групп процессов. В широких пределах процесс может изменять группы процессов (хотя в любой момент он принадлежит только одной группе процессов). Варианты обработки сеанса более ограничены; по сути, процесс либо остается участником своего исходного сеанса, либо может сделать себя лидером нового сеанса.
Копирование части вопроса:
Наш конечный уровень отправляет SIGINT процессу переднего плана (группе, чей идентификатор должен равняться PID лидера группы). В этом случае этот процесс переднего плана (наше приложение «login») становится лидером группы, вызывая setsid. Когда пользователь входит в систему, программа разветвляется и запускает оболочку пользователя. На этом этапе я понимаю, что я вызываю setpgid от разветвленного потомка перед вызовом exec *. Это означает, что выполненная программа с самого начала будет частью группы процессов.
Я подозреваю, что круглые скобки должны быть «группой процессов переднего плана (чей идентификатор должен равняться PID лидера группы)». По определению (3.292) лидер группы процессов - это процесс, PID которого совпадает с идентификатором группы процессов. Я не цитирую соответствующий материал, но считаю, что отправка сигнала руководителю группы процессов правильна
Обратите внимание, что процесс переднего плана становится лидером сеанса, вызывая setsid()
, а также становится лидером группы процессов. Я ожидаю, что программа входа в систему установит пользовательскую оболочку в качестве лидера группы процессов (и, вероятно, лидера сеанса) после разветвления, но до запуска оболочки. Все дочерние процессы автоматически наследуют группу процессов и сеанс от своих родительских процессов; Вы должны переопределить это, если хотите, чтобы оно было другим.
Если бы я хотел запустить вновь разветвленного потомка за пределами группы процессов, я бы просто вызвал setsid в разветвленном потомке перед вызовом exec *.
Вы можете сделать это, но это также создаст новую сессию. Вы, вероятно, хотите использовать setpgid()
(современный стандарт; возможно, setpgrp()
, который является более старым стандартом от SVID), а не setsid()
.
Это правильно? Есть ли какие-то неясные вещи, которые я должен проверять или делать?
Да, это в основном правильно. Да, вероятно, есть некоторые неясные вещи, которые нужно отслеживать. Например, вам может понадобиться подумать об управляющем TTY.
В качестве дополнительного вопроса, который, я полагаю, я уже знаю, является ли обязательным требование для команды fork для передачи членства в группах? Или это должно быть сделано с помощью setpgid после каждого вызова fork? Я понимаю, что группы процессов передаются с помощью fork из определения POSIX для fork.
Дочерний процесс после fork()
принадлежит к тому же набору групп (как в /etc/group
), а также к тому же сеансу и той же группе процессов - но он не является лидером сеанса и не является группой процессов лидер.