进程组、会话、控制终端

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、只有 非 group leader 才能创建 session(见 setsid())

3、如果一个进程能新建 session, 那么新建 session 的同时, 必定新建 process group, 并且使这个进程成为 session leader 和 process group leader

4、能获得控制终端(controlling terminal)的必定是 session leader, 因此,如果一个进程不是 session leader, 则这个进程不可能获得控制终端




  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值