Почему fork () перед setsid () - PullRequest
       9

Почему fork () перед setsid ()

37 голосов
/ 10 апреля 2010

Зачем fork() до setsid() демонизировать процесс?

Обычно, если я хочу отсоединить процесс от его управляющего терминала и сделать его лидером группы процессов: я использую setsid().

Делать это без разветвления раньше не получится.

Почему?

Ответы [ 3 ]

52 голосов
/ 10 апреля 2010

Прежде всего: setsid () сделает ваш процесс лидером группы процессов, но он также сделает вас лидером нового сеанса. Если вы просто заинтересованы в получении собственной группы процессов, используйте setpgid (0,0).

Теперь, чтобы понять реальную причину, почему setsid () возвращает EPERM, если вы уже являетесь лидером группы процессов или лидером сеанса, вы должны понимать, что идентификаторы группы процессов и сеанса инициализируются из идентификатора процесса создавшего их процесса (и, следовательно, их, т. е. для лидера сеанса pid == sid и для лидера группы процессов pid == pgid). Также группы процессов не могут перемещаться между сеансами.

Это означает, что если вы являетесь лидером группы процессов, и создание нового сеанса будет разрешено, тогда sid и pgid будут установлены на ваш pid, оставляя другие процессы в вашей старой группе процессов в странном состоянии: их процесс Лидер группы неожиданно оказывается на другой сессии, чем они сами. И это не может быть допущено, следовательно, EPERM ядром.

Теперь, если вы выполняете fork (), когда уже не являетесь ни сессией, ни лидером группы процессов, и, следовательно, установка sid и pgid для pid безопасна, потому что в этой группе нет других процессов.

Итак, даааа, подумай об этом, все это имеет смысл.

18 голосов
/ 10 апреля 2010

Требуется fork() и иметь дочерний вызов setsid(), чтобы гарантировать, что вызывающий процесс setsid() уже не является лидером группы процессов (setsid() хочет сделать вызывающий процесс лидером группы процессов новая группа процессов, поэтому в этом случае происходит сбой).

2 голосов
/ 05 марта 2014

man 2 setsid, вы получите следующее описание:

setsid () создает новый сеанс, если вызывающий процесс не является лидером группы процессов. Вызывающий процесс является лидером нового сеанса, лидером группы процессов новой группы процессов и не имеет управляющего терминала. Идентификатор группы процессов и идентификатор сеанса вызывающего процесса устанавливаются в PID вызывающего процесса. Вызывающий процесс будет единственным процессом в этой новой группе процессов и в этом новом сеансе.

Если руководителю группы процессов разрешено вызывать setsid(), создать новый сеанс и новую группу процессов (с тем же идентификатором группы процессов), это приведет к конфликту идентификаторов группы процессов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...