博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Unix环境高级编程(八)进程关系
阅读量:6346 次
发布时间:2019-06-22

本文共 2665 字,大约阅读时间需要 8 分钟。

  本章看后给人似懂非懂的感觉,主要是不知道实际当中如何去使用。通过前面几章的学习,每个进程都有一个父进程,当子进程终止时,父进程得到通知并取得子进程的退出状态。先将本章基本的知识点总结如下,日后再看时候好好总结一下。

1、终端登录

  介绍了有终端登录Unix系统的过程。通过init进程读文件/etc/ttys,fork一个子进程调用exec执行getty程序进行登录,当用户输入完用户名后,getty的工作完成了,然后调用login程序,类似execle("/bin/login","login","-p",username,(char *)0,envp)。

2、网络登录

  经由内核的网络接口驱动程序,使用伪终端驱动程序,BSD中由inetd进程等待网络连接。具体过程为:inti进程调用一个shell,启动守护进程inetd,等待TCP/IP连接请求达到主机,当一个连接请求到达时,fork一个子进程进行执行相关程序。

3、进程组

  每个进程除了拥有一个进程ID外,还属于一个进程组,进程组是一个或多个进程的集合,每个进程组有一个唯一的进程组ID,可以通过getpgrp函数获取。每个进程组可以有一个组长进程,其进程组ID等于其进程ID。组长进程可以创建一个进程组,创建改组中的进程。通过setpgid函数添加一个现有的组或者创建一个新进程组。

4、会话

  会话(session)是一个或者多个进程组的集合,通常是由shell的管道线将几个进程编程一组。进程调用setsid函数创建一个新会话,getsid函数返回调用进程的会话首进程的进程组ID。

5、控制终端

  一个会话可以用一个控制终端;建立与控制终端连接的会话首进程称为控制进程;一个会话中的几个进程组可以分为前台进程组和后台进程组;一个会话中只有一个前台进程组,但可以有多个后台进程组;中断(Ctrl+C,SIGINT)、退出(Ctrl+/,SIGQUIT)和挂起(Ctrl+Z,SIGTSTP)字符产生的信号发送到前台进程组。

6、作业控制

  在一个终端上启动多个作业(进程组),控制作业在前后台运行。作业控制需要3个方面的支持和协作:(1)Shell本身的支持;(2)内核的终端驱动程序的支持;(3)内核对作业控制信号的支持。

7、shell执行程序

  采用ps命令输出进程ID,父进程ID,进程组ID,会话ID,命令。

      ps -o pid,ppid,pgid,sid,comm

8、孤儿进程组

  一个父进程已经终止的进程称为孤儿进程(orphan process),这种进程由init进程收养。当一个控制进程结束后,其控制终端也会被释放,其他的session可以使用该终端作为控制终端。为了防止旧session中的进程尝试继续使用该终端,提出了孤儿进程组的概念。孤儿进程组就是指那些session leader已经终止,却还在继续执行的进程组。当进程组成为孤儿进程组时,内核会发送SIGHUP信号到该进程组中的所有进程。对于SIGHUP信号,默认情况下是终止进程。但用户可以捕捉此信号,从而不被终止,但是还是不能访问终端。孤儿进程组定义:改组中每个成员的父进程要么是该组的一个成员,要么不是该组所属会话的成员。一个进程组不是孤儿进程组的条件是:该组有一个进程,它的父进程在属于同一会话的另一个组中。

创建一个孤儿进程组程序如下:

1 #include 
2 #include
3 #include
4 #include
5 #include
6 #include
7 #include
8 9 static void sig_hup(int signo) 10 { 11 printf("SIGHUP received,pid = %d\n",getpid()); 12 } 13 14 static void pr_ids(char *name) 15 { 16 printf("%s: pid = %d,ppid = %d,pgrp = %d,tpgrp = %d\n", 17 name,getpid(),getppid(),getpgrp(),tcgetpgrp(STDIN_FILENO)); 18 fflush(stdout); 19 } 20 21 int main() 22 { 23 char c; 24 pid_t pid; 25 26 pr_ids("parent"); 27 if((pid = fork()) < 0) 28 { 29 perror("fork() error"); 30 exit(-1); 31 } 32 else if(pid > 0) 33 { 34 sleep(5); 35 exit(0); 36 } 37 else 38 { 39 pr_ids("child"); 40 signal(SIGHUP,sig_hup); 41 kill(getpid(),SIGTSTP); 42 pr_ids("child"); 43 if(read(STDIN_FILENO,&c,1) != 1) 44 printf("read error form controlling tty,errno = %d\n",errno); 45 exit(0); 46 } 47 }

执行结果如下:

补充一下:

PID = 进程ID (由内核根据延迟重用算法生成)

PPID = 父进程ID(只能由内核修改)
PGID = 进程组ID(子进程、父进程都能修改)
SID = 会话ID(进程自身可以修改,但有限制,详见下文)
TPGID= 控制终端进程组ID(由控制终端修改,用于指示当前前台进程组)

僵尸进程:先于父进程终止,但是父进程没有对其进行善后处理(获取终止子进程有关信息,释放它仍占有的资源)。消灭僵尸进程的唯一方法是终止其父进程。

孤儿进程:该进程的父进程先于自身终止。其特点是PPID=1(init进程的ID)。一个孤儿进程可以自成孤儿进程组。

进程属于一个进程组,进程组属于一个会话,会话可能有也可能没有控制终端

转载地址:http://kicla.baihongyu.com/

你可能感兴趣的文章
铁路开通WiFi“钱景”不明
查看>>
Nutanix领衔的超融合能带来新存储黄金时代吗?
查看>>
Facebook申请专利 或让好友及陌生人相互拼车
查看>>
电力“十三五”规划:地面光伏与分布式的分水岭
查看>>
美联社再告FBI:要求公开请黑客解锁iPhone花费
查看>>
三星电子出售希捷和夏普等四家公司股份
查看>>
任志远:当云计算遇上混合云
查看>>
思科联手发那科 用物联网技术打造无人工厂
查看>>
智慧城市首要在政府利用大数据的智慧
查看>>
2015年物联网行业:巨头展开专利大战
查看>>
以自动化测试撬动遗留系统
查看>>
网络安全初创公司存活之道
查看>>
《图解CSS3:核心技术与案例实战》——1.2节浏览器对CSS3的支持状况
查看>>
《Android应用开发》——2.4节应用类
查看>>
继 One Step 后,锤子科技 Big Bang 正式开源
查看>>
《淘宝店铺经营管理一册通》一一1.4 商品发布
查看>>
《数据科学:R语言实现》——2.5 使用Excel文件
查看>>
《淘宝店铺设计装修一册通》一2.5 抠图工具的简单运用
查看>>
《音乐达人秀:Adobe Audition实战200例》——实例4 收音机音乐节目转录到电脑里...
查看>>
《JavaScript应用程序设计》一一3.1 过时的类继承
查看>>