热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

UNIX环境高级编程进程关系

    相关函数列表 //返回调用进程的进程组ID#includ



 

 


相关函数列表

//返回调用进程的进程组ID
#include
pid_t getpgrp(void);
pid_t getpgid(pid_t pid);
//getpgid(0) 等于 getpgrp()
//创建一个新会话
#include
pid_t setsid(void);
pid_t getsid(get_t pid); //返回会话首进程的进程组ID
//对于setsid()函数,如果调用此函数的进程不是一个进程组的组长,则此函数创建一个新会话
//1.该进程变成新会话的会话首进程(session leader会话首进程是创建该会话的进程),此时,该进程
// 是新会话中唯一进程
//2.该进程成为一个新进程组的组长进程。新进程组ID是该调用进程的进程ID
//3.该进程没有控制终端,如果在调用setsid之前该进程有一个控制终端,那么这种联系也被切断
//根据FD获取哪个进程组是前台进程组
#include
pid_t tcgetpgrp(int fd);
int tcsetpgrp(int fd, pid_t pgrpid);
//给出控制TTY的文件描述符,下面函数可以获得会话首进程的进程组ID
#include
pid_t tcgetsid(int fd);

 

 

 


终端登录

系统管理者创建/etc/ttys文件,之后init进程读取这个文件,然后fork新进程执行exec调用getty程序

getty对终端设备调用open函数,以读写方式将终端打开,一旦设备打开,则文件描述符就被设置到该设备,然后getty输出“login”之类的信息。getty会根据波特率适当的更改终端的速度。

当用户输入用户名后,getty工作就完成了,然后它调用login程序

execle("/bin/login", "login" "-p", username, (char*)0, envp);

最初的init进程有超级用户权限,所以它fork后的进程都有超级用户权限 

login能处理多项工作,得到用户名调用getpwnam取得相应的用户口令,然后调用getpass提示"password",用户输入口令后,调用crypt将用户口令加密,并与阴影文件的pw_passwd字段比较,如果出错则login调用exit表示登陆失败,父进程init了解到子进程情况后再次调用fork又执行getty,重复上述过程


UNIX环境高级编程 进程关系

如果用户登陆正常login就将完成如下工作:

1)将当前工作目录更改为用户的起始目录(chdir)

2)调用chown更改该终端的所有权,使登陆用户成为它的所有者

3)将对该终端设备的访问权限改变为“用户读和写”

4)调用setgid以及initgroups设置进程的组ID

5)用login得到所有信息初始化环境:起始目录(HOME),shell(SHELL),用户名(USER和LOGNAME)以及一个

   系统默认路径(PATH)

6)login进程更改为登陆用户的用户ID(setuid)并调用该用户的登陆shell,其方式类似于

execl("/bin/sh", "-sh", (char*)0);

 

 


网络登陆

init进程调用一个shell,使其执行shell脚本/etc/rc,由此shell脚本启动一个守护进程inetd。一旦shell脚本终止,inetd的父进程就变成init。inetd等待TCP连接达到主机,然后执行一次fork,生成子进程exec执行适当的程序。

当telnet请求达到后,inetd会fork一个进程,然后执行telnetd程序(exec调用),之后分成两个进程,父进程继续处理连接的通讯,子进程执行login程序,父进程和子进程通过伪终端相连接。

执行过程:

1.init调用fork和exec启动inetd

2.inetd接收到客户端的telnet连接,然后fork新进程

3.inetd继续接受客户来的连接,新进程调用exec启动telnetd处理用户逻辑

 


会话

进程组是一个或多个进程的集合,会话是一个或多个进程组的集合

比如proc1 | proc2 & | proc3 | proc4 | proc5

 

会话和进程组还有一些其他特性

1.一个会话可以有一个控制终端(controlling terminal),这通常是终端设备(在终端登录)或伪终端设备(网络)

2..建立与控制终端连接的会话首进程被称为控制进程(controlling process)

3.一个会话中的几个进程组可被分成一个前台进程组(foreground process group)以及一个或多个后台进程

   组(background process group)

4.如果一个会话有一个控制终端,则它有一个前台进程组,其他进程组为后台进程组

5.无论何时键入终端的中断键,都会将终端信号发送至前台进程组的所有进程

6.如果终端接口检测到调制解调器(或网络)已断开连接,则将挂断信号发送至控制进程(会话首进程)


UNIX环境高级编程 进程关系


 

 

 


作业控制

允许在一个终端上启动多个作业(进程组),它控制一个作业可以访问该终端以及哪些作业在后台运行。要求以下三种形式的支持:

1.支持作业控制的shell

2.内核中的终端驱动程序必须支持作业控制

3.内核必须提供对某些作业控制信号的支持

 

//这里启动了两个作业
pr *.c | lpr &
make all &
//在后台运行,之后又将作业1号变为前台运行
cat > temp.foo &
fg %1
stty tostop //禁止作业输出至控制终端

 对于前台,后台作业以及终端驱动程序的作业控制功能总结




UNIX环境高级编程 进程关系


 



 

 


shell执行程序

//执行下面这段shell
ps -o pid,ppid,pgid,sid,tpgid,comm | cat | cat | tail | more | head
//结果
PID PPID PGID SID TPGID COMMAND
26383 26381 26383 26383 26514 bash
26456 26383 26450 26383 26514 more
26514 26383 26514 26383 26514 ps
26515 26383 26514 26383 26514 cat
26516 26383 26514 26383 26514 cat
26517 26383 26514 26383 26514 tail
26518 26383 26514 26383 26514 more
26519 26383 26514 26383 26514 head

 从结果中可以看到,所有的命令都父进程ID都是bash,也就是bash去启动了那些命令

而ps,cat,cat,tail,more,head这些命令是在一个进程组中的。同时上面所有的进程都是在一个会话中

Bourne shell执行管道ps | cat1 | cat2时的进程


UNIX环境高级编程 进程关系


这里执行的sh后,又会fork一个新进程,然后这个新的sh进程再去fork一些子进程,fork的这些子进程都是执行

sh命令,这些sh命令又调用exec函数执行不同的shell命令,比如ps,cat这样的

管道中最后一个shell命令是由最初的sh(PID为202)调用exec执行的

当然这里不同的sh执行会有不同的效果,而且创建的进程顺序也会不同

linux上的bash shell对于所有的执行的管道命令都是bash的子进程 

 


通过pstree命令执行

ps -o pid,ppid,gid,sid,comm | cat | more | head | pstree
//结果
init-+-bash
|-6*[mingetty]
|-sshd---sshd-+-bash
| `-bash-+-cat
| |-head
| |-more
| |-ps
| `-pstree
`-udevd

可以看到init进程for了sshd(也就是终端),然后sshd又fork了bash,

bash调用exec再fork了cat,head,more,ps等命令,生成相应的进程

 

 

 


孤儿进程组

一个其父进程已经终止的进程称为孤儿进程(orphan process),这种进程由init进程收养,而整个进程组也有可能成为孤儿。

POSIX.1将孤儿进程组(orphaned process group)定义为:

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

对孤儿进程组的另一种描述可以使:

一个进程组不是孤儿进程组的条件是---该组中有一个进程,其父进程在属于同一会话的另一个组中。如果进程组

不是孤儿进程组,name在属于同一会话另一个组中的父进程就有机会重新启动该组中停止的进程。在这里,进程组中每一个进程的父进程都属于另一个会话。所以此进程组是孤儿进程组。

 

 

 


FreeBSD实现

会话和进程组的FreeBSD实现


UNIX环境高级编程 进程关系


session结构体

1)s_count是该会话中的进程组数。当此计数器减至0时,则可释放此结构

2)s_leader是指向会话首进程proc结构体的指针

3)s_ttyvp是指向控制终端vnode结构的指针

4)s_ttyp是指向控制终端tty结构的指针

5)s_sid是会话id

 

tty结构体

1)t_session指向将此终端作为控制终端的session结构(注意,tty结构指向session结构,session结构也指向

   tty)。终端在市区载波信号时使用此指针将挂起信息发送给会话首进程

2)t_pgrp是指向前台进程组的pgrp结构。终端驱动程序用此字段将信号发送给前台进程组。

3)t_termios是包含所有这些特殊字符和与该终端有关信息(如波特率,回显打开或关闭)的结构

4)t_winsize是包含终端窗口当前大小的winsize型结构。当终端窗口大小改变时,信号SIGWINCH被发送至前台

   进程组。

 

pgrp结构体(包含一个特定进程组的信息)

1)pg_id是进程组ID

2)pg_session指向此进程组所属会话的session结构

3)pg_members是指向此进程组proc结构表的指针,该proc结构代表进程组的成员

 

proc结构体

1)p_pid包含进程ID

2)p_pptr是指向父进程proc结构的指针

3)p_pglist是一个结构,其中包含两个指针,分别指向进程组中上一个和下一个进程

最后还有一个vnode结构,在打开控制终端设备时分配此结构体,进程对/dev/tty的所有访问都通过vnode。

 

 

 

 

 

 

 


UNIX环境高级编程 进程关系




推荐阅读
  • 服务器部署中的安全策略实践与优化
    服务器部署中的安全策略实践与优化 ... [详细]
  • Linux Shell变量初探:初始值解析与使用指南
    本文探讨了Linux Shell中变量的基本概念及其在BASH中的应用。变量是用于存储可变数据的标识符,能够代表不同的值。文章详细介绍了BASH shell的主要优势,包括强大的命令编辑能力、自动补全功能、命令别名设置、作业控制以及前后台任务管理。此外,还涵盖了编程脚本编写和通配符的使用方法,为初学者提供了全面的指导。 ... [详细]
  • 本文详细介绍了在 Ubuntu 系统上搭建 Hadoop 集群时遇到的 SSH 密钥认证问题及其解决方案。通过本文,读者可以了解如何在多台虚拟机之间实现无密码 SSH 登录,从而顺利启动 Hadoop 集群。 ... [详细]
  • Shell脚本编译器的全面解析与应用指南 ... [详细]
  • 数字图书馆近期展出了一批精选的Linux经典著作,这些书籍虽然部分较为陈旧,但依然具有重要的参考价值。如需转载相关内容,请务必注明来源:小文论坛(http://www.xiaowenbbs.com)。 ... [详细]
  • 在开发过程中,我最初也依赖于功能全面但操作繁琐的集成开发环境(IDE),如Borland Delphi 和 Microsoft Visual Studio。然而,随着对高效开发的追求,我逐渐转向了更加轻量级和灵活的工具组合。通过 CLIfe,我构建了一个高度定制化的开发环境,不仅提高了代码编写效率,还简化了项目管理流程。这一配置结合了多种强大的命令行工具和插件,使我在日常开发中能够更加得心应手。 ... [详细]
  • 本文介绍了如何在 Windows 系统上利用 Docker 构建一个包含 NGINX、PHP、MySQL、Redis 和 Elasticsearch 的集成开发环境。通过详细的步骤说明,帮助开发者快速搭建和配置这一复杂的技术栈,提升开发效率和环境一致性。 ... [详细]
  • 在Ubuntu系统中配置Python环境变量是确保项目顺利运行的关键步骤。本文介绍了如何将Windows上的Django项目迁移到Ubuntu,并解决因虚拟环境导致的模块缺失问题。通过详细的操作指南,帮助读者正确配置虚拟环境,确保所有第三方库都能被正确识别和使用。此外,还提供了一些实用的技巧,如如何检查环境变量配置是否正确,以及如何在多个虚拟环境之间切换。 ... [详细]
  • 如何利用Git实现高效的多人协作开发(远程仓库应用实例)——Ares Zhao
    Git作为一种分布式版本控制系统,每位开发者都是本地仓库的管理者。然而,为了实现团队间的高效协作,需要将本地的开发成果推送至远程共享仓库,以便其他成员能够同步更新。本文将以GitHub为例,详细介绍如何通过设置和使用远程仓库,实现多人协作开发的最佳实践。 ... [详细]
  • 在Linux环境中,通过编写Shell脚本来实现自定义命令的创建与激活,能够极大地简化服务器上多个子系统的管理操作。例如,通过简单的命令如“tt”,即可快速查看各个应用程序的名称及其运行状态,从而提高系统维护的效率和便捷性。 ... [详细]
  • 本文整理了一份基础的嵌入式Linux工程师笔试题,涵盖填空题、编程题和简答题,旨在帮助考生更好地准备考试。 ... [详细]
  • Python错误重试让多少开发者头疼?高效解决方案出炉
    ### 优化后的摘要在处理 Python 开发中的错误重试问题时,许多开发者常常感到困扰。为了应对这一挑战,`tenacity` 库提供了一种高效的解决方案。首先,通过 `pip install tenacity` 安装该库。使用时,可以通过简单的规则配置重试策略。例如,可以设置多个重试条件,使用 `|`(或)和 `&`(与)操作符组合不同的参数,从而实现灵活的错误重试机制。此外,`tenacity` 还支持自定义等待时间、重试次数和异常处理,为开发者提供了强大的工具来提高代码的健壮性和可靠性。 ... [详细]
  • Android 构建基础流程详解
    Android 构建基础流程详解 ... [详细]
  • 本文介绍了如何利用Shell脚本高效地部署MHA(MySQL High Availability)高可用集群。通过详细的脚本编写和配置示例,展示了自动化部署过程中的关键步骤和注意事项。该方法不仅简化了集群的部署流程,还提高了系统的稳定性和可用性。 ... [详细]
  • MySQL 8.0 MGR 自动化部署与配置:DBA 和开源工具的高效解决方案
    MySQL 8.0 MGR 自动化部署与配置:DBA 和开源工具的高效解决方案 ... [详细]
author-avatar
PHP白姐
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有