pag214
登录简易流程:
进程组使一个或多个进程的集合,通常他们与同一作业相关联,可以接收来自统一终端的各种信号。
pid_t getpgrp(void);//返回调用进程的进程组ID
pid_t getpgid(pid_t pid);//返回pid进程的进程组ID(getpgid(0) = getpgrp())
int setpgid(pid_t pid, pid_t pgid);//加入现有组或创建一个新进程组
进程组:
每个进程组都可以有一个组长进程。 组长进程的标识是,其 进程组ID等于其进程ID。
组长进程可以创建一个进程组,创建该组中的进程,然后终止。只要在 某个进程组中有一个进程存在,则 该进程组就存在,这 与其组长进程是否终止无关。
一个进程只能为他自己或他的子进程设置进程组ID。在他的 子进程调用了exec函数之一后,他就不能改变该子进程的进程组ID。
pag219
会话是一个或多个进程组的集合。
pid_t setsid(void);//建立新会话
调用进程不是一个进程组的组长,此函数创建一个新会话:
pid_t tcgetpgrp(int filedes);//返回前台进程组的进程组ID,该前台进程组与在filedes上打开的终端相关联
int tcsetpgrp(int filedes, pid_t pgrpid);//将前台进程组ID设置为pgrpid(同一会话中的进程组ID),filedes必须引用会话的控制终端
pid_t tcgetsid(int filedes);//获得会话首进程的进程组ID
pag229
孤儿进程组:
一个进程组 不是孤儿进程组的条件是,该组中有一个进程,其父进程在属于 同一会话中的另一组中。
父进程终止时,子进程被置入后台进程组中,shell所在进程组成为前台进程组(程序9-1)
习题9-2
#include
#include
#include
#include
#include
int
main(int argc, char *argv[])
{
pid_t
pid, sid;
printf("father\n");
printf("gid:%d\n", getpgid(0));
printf("session fgid:%d\n", tcgetpgrp(STDOUT_FILENO));
if ((pid = fork()) == 0) {
sleep(2);
sid = setsid();
printf("\nchild\n");
printf("gid:%d sid:%d\n", getpgid(0), sid);
printf("session fgid:%d\n", tcgetsid(STDOUT_FILENO));
exit(0);
}
输出:
father
gid:5761
session fgid:5761
root@ubuntu:~/other#
child
gid:5762 sid:5762
session fgid:-1
(可知新会话无控制终端)
登录简易流程:
- init进程fork子进程exec执行getty
- getty开启终端设备以便输入,显示Login:
- 用户输入用户名
- getty程序exec执行login程序
- login由用户名(getpwnam)获取pw结构,显示Password:
- 用户输入密码
- login程序比对pw结构中pw_passwd
进程组使一个或多个进程的集合,通常他们与同一作业相关联,可以接收来自统一终端的各种信号。
pid_t getpgrp(void);//返回调用进程的进程组ID
pid_t getpgid(pid_t pid);//返回pid进程的进程组ID(getpgid(0) = getpgrp())
int setpgid(pid_t pid, pid_t pgid);//加入现有组或创建一个新进程组
- pid=pgid, pid指定进程变成进程组组长
- pid=0, 使用调用者进程PID
- pgid=0, pid指定进程ID作为进程组ID
进程组:
每个进程组都可以有一个组长进程。 组长进程的标识是,其 进程组ID等于其进程ID。
组长进程可以创建一个进程组,创建该组中的进程,然后终止。只要在 某个进程组中有一个进程存在,则 该进程组就存在,这 与其组长进程是否终止无关。
一个进程只能为他自己或他的子进程设置进程组ID。在他的 子进程调用了exec函数之一后,他就不能改变该子进程的进程组ID。
pag219
会话是一个或多个进程组的集合。
pid_t setsid(void);//建立新会话
调用进程不是一个进程组的组长,此函数创建一个新会话:
- 该进程变成新会话首进程,并且是此时新会话中的唯一进程
- 该进程成为一个新进程组的组长进程。新进程组ID是该调用进程的进程ID
- 该进程没有控制终端。如在调用之前有,则联系中断
pid_t getsid(pid_t pid); //返回会话首进程的进程组ID
一个会话可以有一个控制终端。
建立与控制终端连接的会话首进程被称为控制进程。
pid_t tcgetpgrp(int filedes);//返回前台进程组的进程组ID,该前台进程组与在filedes上打开的终端相关联
int tcsetpgrp(int filedes, pid_t pgrpid);//将前台进程组ID设置为pgrpid(同一会话中的进程组ID),filedes必须引用会话的控制终端
pid_t tcgetsid(int filedes);//获得会话首进程的进程组ID
pag229
孤儿进程组:
一个进程组 不是孤儿进程组的条件是,该组中有一个进程,其父进程在属于 同一会话中的另一组中。
父进程终止时,子进程被置入后台进程组中,shell所在进程组成为前台进程组(程序9-1)
习题9-2
#include
#include
#include
#include
#include
int
main(int argc, char *argv[])
{
输出:
father
gid:5761
session fgid:5761
root@ubuntu:~/other#
child
gid:5762 sid:5762
session fgid:-1