linux祖先进程,Linux下的几种特殊进程
1、Linux的登录环境
Linux是一个多任务多用户的操作系统,其设计初衷: 就是要达成多用户同时使用单个计算机大的任务。
多用户:早期计算机资源紧张,为了让更多的人都可以使用。
多任务:服务于多用户,同时提高计算机的吞吐量。
早期登录就是通过哑终端连接登录的。
早期登录Linux模型
随着以太网的发展,Linux的出现,在进行多用户连接时候,充分使用了以太网。提高了应用层的网络服务,这些网络服务替代了之前的轮询监控串口的服务进程。ssh相对于Telnet就是加密了,更加安全。
2、进程组
在Linux下进程除了具有父子关系这样的组织关系以外,还具有分组的组织关系,任何一个进程都需要隶属于某个进程组。
每一个进程组都拥有一个独立的进程组编号,可以通过getpgid()方法得到。
每一个进程组都拥有且只拥有一个组长进程。可以通过该组长管理其组内的其它进程的统一行为。(例如:组长进程若获取一个特殊的信号,该信号可以传递给组内所有进程)。
进程组ID就是该进程组组长的进程ID。
进程组内的成员都是组长的子及子孙。
3、会话
每一个进程除了要归属一个进程组以外,还需要归属于一个会话之中。会话的概念主要是从终端登录到计算机之后得到的。
当一个终端登录到计算机之后,为了方便将不同的终端隔离开,同时又能够充分合理的管理一个终端下产生的所有进程,因此而提出了会话的概念。换句话来说,会话就是用户登录之后从登录服务进程到shell进程所组成的集合。
从逻辑上来讲,会话就控制了计算机和某一个终端的一个连续的交互过程。
一个会话通常是由多个进程组组成的,分为两部分(前台进程组、后台进程组)。
会话具有一个会话首进程。操作系统通过会话的首进程来管理整个会话中的所有进程组。
(1)、前台进程组
是和终端服务进程、bash进程捆绑在一起的,和终端直接相关。那么,终端的任何操作都会影响到所有的前台进程组。
在shell交互环境中执行一个命令,就会产生一个新的进程来执行这个命令,不仅如此,还会产生一个新的进程组,该进程组的组长就是被执行命令而形成的新进程。
前台进程组的最大问题就在于,需要看终端的脸色!终端只需要让进程组的组长停止,其内部的所有进程都会停止。
(2)、后台进程组
断开与终端的关系(并非输入、输出、错误输出关系),进程组关系,不在受制于终端而存在,这种进程与进程组被称之为后台的。
后台进程存在的理由就是,需要常驻内存,提供一个服务。
4、进程组如何创建
创建一个新的进程组的方式有2种,这2种有区别:
(1)、通过调用setpgid()能够将调用该方法的当前进程设置为新的进程组的组长。从而创建一个新的进程。
(2)、通过调用setsid()方法来创建一个新的会话,从而就会出现新的进程组,调用setsid()方法的进程就会成为会话的首进程,新进行组的组长。
5、僵尸进程
在Linux操作系统设计中,要求进程结束的时候需要告知其父进程该进程的结束,父进程也需要知道其子进程结束的状态,这是因为父进程有些时候需要根据子进程结束的状态来作一些后续的操作。
进程的消亡:
(1)、进程调用了exit()方法,通知操作系统内存,当前进程想要结束自己的生命;
(2)、操作系统此时就会立即回收进程的几乎所有的主要内容,然后告知其父进程,它的某一个子进程结束;
(3)、父进程需要明确的答复操作系统内核,已收到子进程结束的消息。否则,操作系统内核会一直保存该将要结束进程的部分PCB信息。同时将进程的状态置为defunct。这就是僵尸进程。
i>、僵尸进程是不能够被直接消除掉的。
ii>、僵尸进程的危害: 占用PCB资源(PID资源)。
iii>、子进程先于父进程结束,父进程没有收尸,就是僵尸进程。
其产生僵尸进程的代码如下:#include
#include
#include
int main(void){
pid_t pid;
pid = fork();
if(pid == 0){
printf("This is child, will finish. pid = %d\n", getpid());
}else if(pid > 0){
while(1){
printf("This is father, run allways. pid = %d childPid = %d\n", getpid(), pid);
sleep(1);
}
}else{
perror("");
}
return 0;
}
运行结果
如何解决僵尸进程的问题?避免僵尸进程的产生。
解决僵尸进程的根本就在于父进程需要处理子进程的结束。通过调用wait()函数族来进行解决。wait会等待子进程的结束,调用wait的进程会阻塞,直到接受到子进程的结束消息时才会被唤醒。父进程等待子进程的结束消息为SIGCHLD(17)信号。
解决僵尸进程的代码 :#include
#include
#include
int main(void){
pid_t pid;
pid = fork();
if(pid == 0){
int i;
for(i = 0; i
printf("This is child, will finish. pid = %d\n", getpid());
sleep(1);
}
}else if(pid > 0){
int status;
wait(&status); //很好的处理了僵尸进程。
printf("child has gone, status = %d\n", status);
while(1){
printf("This is father, run allways. pid = %d childPid = %d\n", getpid(), pid);
sleep(1);
}
}else{
perror("");
}
return 0;
}
此时就会造成父进程一开始什么也干不了,只能等待子进程的结束,自己才能开始运行。
僵尸进程的解决其实是进程回收进程。
6、孤儿进程
如果某一个进程的父进程先于自己结束,那么该进程还有父进程吗?必须有,因为在Linux下所有的进程都必须存在于整个进程树之中,不允许完全孤立的存在。
如果发生父进程先于子进程结束的情况,则将子进程过继给编号为1的进程,即就是init/systemd进程。
然而此时该进程的进程组关系已经打乱。它所在的进程组不在是其父进程或祖先进程。因为,此时子进程依然保留之前的进程组信息,但是很显然这个进程组与会话信息已经不对了。
这种进程就是孤儿进程,失去了原有的所有进程组与会话关系的进程。所以也会将init/systemd进程称之为孤儿院进程,因为它收养了很多孤儿。
因为子进程的父进程结束,所以其组的组长的信号就不能够传递给该孩子进程。从而使得该子进程就脱离了原有的进程组关系、脱离了原有的会话关系。虽然它保留了原有的进程组和会话ID,但是已经不起任何作用了。
产生孤儿进程的代码 :#include
#include
int main(void){
pid_t pid;
pid = fork();
if(pid == 0){
while(1){
printf("This is along child, pid = %d, pgid = %d sid = %d\n", getpid(), getpgid(getpid()),
getsid(getpid()));
sleep(1);
}
}else if(pid > 0){
printf("This is father, pid = %d, pgid = %d sid = %d\n", getpid(), getpgid(getpid()), getsid(getpi
d()));
}else{
perror("");
}
return 0;
}
此时孤儿进程产生,将用ctrl+c终止不下来,只能用kill PID进行杀死该孤儿进程了。
7、守护进程
守护一个服务,长期驻留在内存中提供服务,不能够受制于终端。通常指的就是操作系统中的服务进程。这些服务进程通常约定其名称最后一个字母为d。
守护进程的另外一个名字 : 精灵进程(demon)。
如何让一个进程成为守护进程? 让一个进程脱离前台进程组关系即可(这样就可以摆脱终端对它的控制)。
怎样让进程脱离前台进程组? 1)、创建一个新的会话;2)、构成孤儿进程。
通常让这两个步骤都进行。
守护进程的创建过程:pid_t pid;
pid = fork();
if(pid == 0){
setsid(); //产生会话进程
while(1){ //子进程一直在运行,迟早会构成孤儿进程。
...
}
}else if(pid > 0){
...
exit(0); //父进程结束
}else{
perror();
}
8、僵尸进程和孤儿进程的一个关联
init/systemd又叫做上帝进程,一手创造了操作系统内部的所有的进程以外,还管理了这些僵尸进程,帮助将其清除掉了。
如果一个进程下产生了僵尸子进程,当该进程结束的时候,会将僵尸进程过继给init/systemd进程,然后init/systemd进程发现过继的新子进程是僵尸进程之后,会为其收尸,从而消除掉已经存在的僵尸进程。
linux祖先进程,Linux下的几种特殊进程相关推荐
- linux vino vnc,Ubuntu下包含2种远程桌面的方式:VINO-Server以及VNC Server。 .
Ubuntu下包含2种远程桌面的方式:VINO-Server以及VNC Server Ubuntu下包含2种远程桌面的方式:VINO-Server以及VNC Server. 其中Vino-Server ...
- linux ps mp,Linux中的命令ps(ps -aux)
ps 为我们提供了进程的一次性的查看,它所提供的查看结果并不动态连续的:如果想对进程时间监控,应该用 top 工具.kill 用于杀死进程. ps命令最常用的还是用于监控后台进程的工作情况,因为后台进 ...
- linux下的几种隐藏技术
0x00 前言 攻击者在获取服务器权限后,会通过一些技巧来隐藏自己的踪迹和后门文件,本文介绍Linux下的几种隐藏技术. 0x01 隐藏文件 Linux 下创建一个隐藏文件:touch .test.t ...
- Linux 下的五种 IO 模型
Linux 下的五种 IO 模型 来源:decaywood's Blog 概念说明 用户空间与内核空间 现在操作系统都是采用虚拟存储器,那么对32位操作系统而言,它的寻址空间(虚拟存储空间)为4G(2 ...
- Linux下1号进程的前世(kernel_init)今生(init进程)----Linux进程的管理与调度
Linux下有3个特殊的进程,idle进程(PID=0PID=0), init进程(PID=1PID=1)和kthreadd(PID=2PID=2) * idle进程由系统自动创建, 运行在内核态 i ...
- Linux下0号进程的前世(init_task进程)今生(idle进程)----Linux进程的管理与调度(五)【转】...
前言 Linux下有3个特殊的进程,idle进程(PID = 0), init进程(PID = 1)和kthreadd(PID = 2) idle进程由系统自动创建, 运行在内核态 idle进程其pi ...
- kill掉多个进程linux中的sudo,linux下批量kill进程的方法
--kill某个用户下的所有进程(用户为test) --pkill # pkill -u test --killall # killall -u test --ps # ps -ef | grep t ...
- Linux技巧:多核下绑定硬件/进程到不同CPU
http://www.51testing.com/html/07/n-222407.html 硬件中断发生频繁,是件很消耗 CPU 资源的事情,在多核 CPU 条件下如果有办法把大量硬件中断分配给不同 ...
- linux创建新进程就分配空间,linux几种创建进程的方法
在Linux中主要提供了fork.vfork.clone三个进程创建方法. 在linux源码中这三个调用的执行过程是执行fork(),vfork(),clone()时,通过一个系统调用表映射到sys_ ...
最新文章
- html5考试总结300字,期中考心得300字5
- Linux内存管理原理【转】
- android 强制设置横屏 判断是横屏还是竖屏
- 解决ubuntu打开windows中txt文件出现乱码现象
- 发达国家农业模式-国际农民丰收节贸易会:全球农业未来
- (选择 冒泡 插入 二分 异或)
- Python3 移动文件——合集
- 从零开始掌握Python机器学习(附不可错过的资源)
- Windows和Linux内存检测工具:Valgrind,Visual Leak Detector,CppCheck, Cpplint
- 《JSP实用教程(第2版)/耿祥义》错误之非必要导入包
- ztree 使用教程
- python菜鸟教程lambda_jQuery(菜鸟教程)
- rs485数据线接反_rs485接口怎么接线?弱电人必学RS485接口基础知识讲解
- 计算机网络结构化布线的六个子系统,结构化网络综合布线系统有六大子系统组成...
- 涉密计算机不得接入 网络,任何组织和个人都不得将涉密计算机、涉密存储设备接入互联网或其他公共信息网络 - 作业在线问答...
- 成就一亿技术人,我和CSDN的九年记忆
- GK309协议电子工牌数据模拟器+Socket数据发送 JAVA版-源码
- oa 服务器 微信,微信OA:一种新的办公方式
- 上海地铁有“世界级”免费Wi-Fi了,整个魔都全嗨了!
- (石头、剪刀、布)shell脚本,随机对比,case的应用