历程组、会话、控制终端
进程组、会话、控制终端
process group - 进程组
session - 会话
controlling terminal - 控制终端
#include <unistd.h> #include <stdlib.h> #include <sys/stat.h> #include <signal.h> #include <syslog.h> #include <fcntl.h> #include <sys/resource.h> int main() { int i, fd0, fd1, fd2; pid_t pid; struct rlimit rl; struct sigaction sa; /* * Clear file creation mask. */ umask(0); /* * Get maximum number of file descriptors. */ if (getrlimit(RLIMIT_NOFILE, &rl) < 0) exit(1); /* [1] */ sleep(5); /* * Become a session leader to lose controlling TTY. */ if ((pid = fork()) < 0) exit(1); else if (pid != 0) /* parent */ exit(0); /* [2] */ sleep(5); setsid(); /* [3] */ sleep(5); /* * Ensure future opens won't allocate controlling TTYs. */ sa.sa_handler = SIG_IGN; sigemptyset(&sa.sa_mask); sa.sa_flags = 0; if (sigaction(SIGHUP, &sa, NULL) < 0) exit(1); if ((pid = fork()) < 0) exit(1); else if (pid != 0) /* parent */ exit(0); /* [4] */ sleep(5); /* * Change the current working directory to the root so * we won't prevent file systems from being unmounted. */ if (chdir("/") < 0) exit(1); /* * Close all open file descriptors. */ if (rl.rlim_max == RLIM_INFINITY) rl.rlim_max = 1024; for (i = 0; i < rl.rlim_max; i++) close(i); /* * Attach file descriptors 0, 1, and 2 to /dev/null. */ fd0 = open("/dev/null", O_RDWR); fd1 = dup(0); fd2 = dup(0); /* * Initialize the log file. */ openlog(NULL, LOG_CONS, LOG_DAEMON); if (fd0 != 0 || fd1 != 1 || fd2 != 2) { syslog(LOG_ERR, "unexpected file descriptors %d %d %d", fd0, fd1, fd2); exit(1); } return 0; } /* [1] 父进程:新建进程组(并且是进程组组长),与bash处于同一回话(bash为session leader) $ ps -u hwx -o pid,ppid,pgid,sid,comm PID PPID PGID SID COMMAND 1038 1037 1038 1038 bash 1425 1038 1425 1038 a.out [2] 第一个子进程,新建回话之前:与父进程处于同一进程组(但不是进程组组长),与bash处于同一回话 $ ps -u hwx -o pid,ppid,pgid,sid,comm PID PPID PGID SID COMMAND 1038 1037 1038 1038 bash 1427 1 1425 1038 a.out [3] 第一个子进程,新建回话之后:新建回话(成为session leader),新建进程组(进程组组长) $ ps -u hwx -o pid,ppid,pgid,sid,comm PID PPID PGID SID COMMAND 1038 1037 1038 1038 bash 1427 1 1427 1427 a.out [4] 第二个子进程:既不是进程组组长,也不是session leader $ ps -u hwx -o pid,ppid,pgid,sid,comm PID PPID PGID SID COMMAND 1038 1037 1038 1038 bash 1432 1 1427 1427 a.out */
说明:
1、
pgid(process group ID) == pid of process group leader
sid(session ID) == pid of session leader
2、如果一个进程能新建 session,那么新建 session 的同时,必定新建 process group,并且是这个进程成为 session leader 和 process group leader
3、能获得控制终端(controlling terminal)的必定是 session leader,因此,如果一个进程不是 session leader,则这个进程不可能获得控制终端