第9章——《进程关系》

实验环境介绍

  • gcc:4.8.5
  • glibc:glibc-2.17-222.el7.x86_64
  • os:Centos7.4
  • kernel:3.10.0-693.21.1.el7.x86_64
终端登录

第9章——《进程关系》_第1张图片

  • login能处理多项工作,能调用getpwnam获取口令登录想,调用getpass提示“Password:”
  • login完成如下工作
    • 当前工作目录改成该用户的其实目录
    • 调用chown更改该终端的所有权,使登录用户成为他的所有者
    • 将对该终端设备的访问权限设置成“用户读和写”
    • 调用setgid以及initgroups设置进程的组ID
    • 用login得到的所有信息初始化环境:HOME、SHELL、USER和LOGNAME以及系统默认PATH
  • 登录shell读取启动文件:.bash_profile、.bash_login、.profile
网络登录
  • 串行终端登录至系统和经由网络登录两者之间的主要区别是:网络登录时,loggin仅仅是一种可用的服务,这和其他网络服务(ftp、smtp)的性质相同。在之前的描述的终端中,init知道哪些终端设备可以用来登录,并为每个设备生成一个getty进程。但是网络登录则不同
  • 系统使用一种伪终端软件驱动来处理终端登录和网络登录。
  • 以telnet来举例:
    第9章——《进程关系》_第2张图片
    第9章——《进程关系》_第3张图片

很明显伪终端到终端用户之间做了很多工作

进程组
  • 忽略
会话

第9章——《进程关系》_第4张图片

  • 上图可能由下面的命令形成:

    • proc1 | proc2 &
    • proc3 | proc4 | proc5
      设置会话
  • setsid创建新会话,如果不是进程组组长,则创建新会话

    • 该进程变成新会话首进程(会话首进程就是创建这个会话的进程)
    • 该进程成为一个新进程组的组长进程。,新进程组id是改调用进程的进程id
    • 该进程没有控制终端,如果调用setsid之前有一个控制终端,那么联系也会被切断。
控制终端
  • 会话和进程组的其他特性:
    • 一个会话可以有一个控制终端。控制终端或者伪终端设备
    • 建立与控制终端连接的会话首进程被称为控制进程
    • 一个会话的几个进程可以分成前台进程组以及一个或多个后台进程组
    • 如果一个会话有一个控制终端,则他有一个前台进程组,其他为后台进程组
    • 介入中断键、退出键,都会将中断信号发送至前台进程组的所有进程
    • 如果中断接口(或者网络)已经断开,则将挂断信号发送至控制进程(会话首进程)
      第9章——《进程关系》_第5张图片
函数tcgetpgrp、tcsetpgrp、tcgetsid
  • 忽略(获取某个终端设备的会话id相关)
作业控制
  • 作业控制的要求
    • 支持作业控制的shell
    • 内核中的终端驱动程序必须支持作业控制
    • 内核必须提供对某些作业控制信号的支持
  • 作业控制的几种信号
    • SIGINT,中断信号
    • SIGQUIT,退出信号
    • SIGTSTP,挂起信号
    • SIGTTIN:后台作业进程,终端驱动会给该后台进程发送该信号
    • SIGTTOU:后台作业进程尝试写的时,终端驱动会给该后台进程发送该信号
    • 测试代码如下:
[manjingliu@localhost part_9]$ ./ttin &
[1] 21667
[manjingliu@localhost part_9]$ xxxxxxxxxxxxxxxxxxxxxxxxx
[manjingliu@localhost part_9]$ xxxxxfgxxxxx %1xxxxx
./ttin
^C

# 这里关闭后台作业进程进行io输入输出
[manjingliu@localhost part_9]$ stty tostop
[manjingliu@localhost part_9]$ ./ttin &   
[1] 21669
[manjingliu@localhost part_9]$ 

[1]+ Stopped ./ttin
[manjingliu@localhost part_9]$ fg %1
./ttin
xxxxxxxxxxxxxxx^C

[manjingliu@localhost part_9]$ strace ./ttin &
[1] 21672
[manjingliu@localhost part_9]$ execve("./ttin", ["./ttin"], [/* 22 vars */]) = 0
brk(NULL) = 0x211a000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f5f1920e000
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=34465, ...}) = 0
mmap(NULL, 34465, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f5f19205000
close(3) = 0
open("/lib64/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0P%\2\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=2173512, ...}) = 0
mmap(NULL, 3981792, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f5f18c21000
mprotect(0x7f5f18de4000, 2093056, PROT_NONE) = 0
mmap(0x7f5f18fe3000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1c2000) = 0x7f5f18fe3000
mmap(0x7f5f18fe9000, 16864, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f5f18fe9000
close(3) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f5f19204000
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f5f19202000
arch_prctl(ARCH_SET_FS, 0x7f5f19202740) = 0
mprotect(0x7f5f18fe3000, 16384, PROT_READ) = 0
mprotect(0x600000, 4096, PROT_READ) = 0
mprotect(0x7f5f1920f000, 4096, PROT_READ) = 0
munmap(0x7f5f19205000, 34465) = 0
write(1, "xxxxx", 5) = ? ERESTARTSYS (To be restarted if SA_RESTART is set)
--- SIGTTOU {si_signo=SIGTTOU, si_code=SI_KERNEL} ---
--- stopped by SIGTTOU ---

第9章——《进程关系》_第6张图片

你可能感兴趣的:(Linux系统编程)