zoukankan      html  css  js  c++  java
  • Apue.2e Chapter9 Process relations

    终端登录过程:

    init读取/ect/ttys,对每一个允许登陆的中断设备fork一次,子进程执行getty程序,getty为终端设备调用open函数(read | write),打开后设置filedes 0,1,2;getty输出login等待用户输入用户名,然后调用login程序(execle传入环境变量)。后者使用getpwnam获得用户口令登陆项,再调用getpass显示提示符提示用户输入密码,然后用crypt将输入的口令加密,再与阴影口令文件中的pw_passwd字段作比较,确定密码的正确性。如果错误,调用exit离开;如果正确,chdir,chown,chmod,setgid,initgroups,setuid,execl /bin/sh,初始化环境变量等等,shell会读取启动文件,然后才能输出shell提示符。

    现代UNIX系统支持PAM(可插入式身份验证模块),允许admin配置身份验证方法。

    网络登陆:

    init调用一个shell,然后执行/etc/rc,启动守护进程inetd,该进程等待TCP/IP请求到达主机,然后fork并执行适当的进程。这里使用了伪终端来模拟login的登陆过程,父进程处理网络通信,子进程则执行login程序(同传统登陆)。

    进程组:

    pid_t getpgrp(void);

    pid_t getpgid(pid_t pid);

    int setpgid(pid_t pid,pid_t pgid);

    进程组id是创建该进程组的进程的id,也就是组长id。

    注意:一个进程只能为自己或子进程设置pid,一旦在子进程中调用了exec系函数,就不能再改变进程组id。为防止竞争条件,往往在父子进程fork后都执行一次setpgid(冗余一次)。

    会话(session):

    会话是进程组的集合,会话id是非Posix的,只有会话首进程(session leader)id,也就是创建会话的进程的id。

    pid_t getsid(pid_t pid);

    如果pid是0,返回调用进程的会话首进程的进程组的pid。如果pid不属于调用者所在的会话,返回错误。

    pid_t setsid(void);

    建立新会话,如果调用该函数的进程已经是一个进程组的组长,则调用失败。新建的绘画没有控制终端。

    控制终端:

    会话的非必需关联物,前台进程组是正在控制终端中运行的进程组,后台则相反。

    可以通过以下函数获得前台进程组:

    pid_t tcgetpgrp(int filedes);

    int tcsetpgrp(int filedes, pid_t pgrpid);

    注意:pgrpid必须是同一会话中的进程组的id;

    作业控制:

    这部分主要讲了常见的作业控制方法(前台、后台等),以及终端驱动程序如何与之交互。

    使用stty可以改变作业控制相关的输出方式;

    shell执行程序:

    具有作业控制和不具有作业控制的shell执行管道命令的方式不同。

    具有作业控制的shell会将前台作业放入它自己的进程组(和shell不同),而不具有作业控制的则相同。

    孤儿进程组:

    进程组的每个成员的父进程要么是该组的一个成员,要么不是该组所属会话中的成员。

    在父进程终止后,Posix.1要求向新的孤儿进程组中处于停止状态的每一个进程发送挂断信号(SIGHUP),接着又向其发送继续信号。

    最后讲了FreeBSD的实现。

  • 相关阅读:
    fdisk 分区
    fdisk 添加逻辑分区
    centos7 bond0 双网卡配置
    查看centos7启动项
    本地yum源安装docker
    cobbler Ubuntu16.04 安装
    docker-ce-17.03.2 离线安装RPM包
    day14 生成器的进阶
    day13迭代器与生成器
    day12闭包,装饰器
  • 原文地址:https://www.cnblogs.com/livewithnorest/p/2890245.html
Copyright © 2011-2022 走看看