进程

先来说下什么是进程:

来看下百度是怎么说的:

光看说的不够形象,在windows系统中,它长这样:

在Mac系统中,它长这样:

Linux中是这样的:(有点长截图一部分好了)

[root@iz2ze76ybn73dvwmdij06zz ~]# ps -ef
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 5月20 ?       00:00:33 /usr/lib/systemd/systemd --system --deserialize 21
root         2     0  0 5月20 ?       00:00:00 [kthreadd]
root         3     2  0 5月20 ?       00:00:06 [ksoftirqd/0]
root         5     2  0 5月20 ?       00:00:00 [kworker/0:0H]
root         7     2  0 5月20 ?       00:00:02 [migration/0]
root         8     2  0 5月20 ?       00:00:00 [rcu_bh]
root         9     2  0 5月20 ?       00:30:40 [rcu_sched]
root        10     2  0 5月20 ?       00:00:17 [watchdog/0]
root        11     2  0 5月20 ?       00:00:16 [watchdog/1]
root        12     2  0 5月20 ?       00:00:02 [migration/1]
root        13     2  0 5月20 ?       00:00:03 [ksoftirqd/1]
root        15     2  0 5月20 ?       00:00:00 [kworker/1:0H]
root        17     2  0 5月20 ?       00:00:00 [kdevtmpfs]
root        18     2  0 5月20 ?       00:00:00 [netns]
root        19     2  0 5月20 ?       00:00:01 [khungtaskd]
root        20     2  0 5月20 ?       00:00:00 [writeback]
root        21     2  0 5月20 ?       00:00:00 [kintegrityd]
root        22     2  0 5月20 ?       00:00:00 [bioset]
root        23     2  0 5月20 ?       00:00:00 [kblockd]
复制代码

OK,以上每一行都是对一个进程的描述,来具体看一下每个参数的含义:

标示 描述 UID 用户ID PID 进程ID PPID 父进程ID C 进程占cpu百分比 STIME 进程启动的时间 TTY 终端机位置 TIME 实际使用cpu的时间 CMD 命令以及参数

我们现在知道了每个参数的含义,既然讲到进程嘛,首先,进程ID是唯一的并且是非负数的,但是进程ID是可以复用的,毕竟进程也会终止。

可以看到没有进程PID是0的,这是为什么呢? 黑人问号脸?

0一般来说是系统进程,属于内核的一部分,不执行任何磁盘上的程序。

fork

一个进程可以通过调用fork函数创建新的进程,被创建出来的这个进程就叫子进程。

这里需要注意一下,fork函数的返回值父子进程区别。

  • 子进程 : 返回值是0,返回0的理由是子进程的父进程是可以唯一确定的,通过getppid方法可以获取到父进程id。
  • 父进程 : 返回的是新创建的子进程的id,因为父进程可以有多个子进程,也没有这样的函数可以获取该线程的子线程的所有id。

下边的话我们来验证一下上说的这一段话。准备好脚本。

#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>int main(int argc, char const *argv[])
{pid_t p1 = fork();printf("%dn",p1);if(p1 > 0){printf("父进程 pid = %d, p1 = %dn", getpid(), p1);}else{printf("子进程 pid = %d , ppid = %d, p1 = %dn", getpid(), getppid(), p1);}return 0;
}
复制代码

运行看结果:

[root@iz2ze76ybn73dvwmdij06zz ~]# ./fork2
10213
父进程 pid = 10212, p1 = 10213
0
子进程 pid = 10213 , ppid = 10212, p1 = 0
复制代码

通过上面的小例子我们可以看到父进程的返回值是子进程的ID,子进程的返回是0。

孤儿进程

孤儿我们都懂就是。。。

是的,没错孤儿进程也是这样的,就是没有父进程的进程。当然创建的时候肯定是要先创建父进程了,当父进程退出时,它的子进程们(一个或者多个)就成了孤儿进程了。

接下来在继续做一个小测试,让父进程现退出。准备好脚本。

[root@iz2ze76ybn73dvwmdij06zz ~]# cat guer.c
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>int main()
{pid_t pid = fork();if (pid < 0) {perror("fork error;");exit(1);} else if (pid == 0) {sleep(5);printf ("子进程 : [ pid] = %d , 父进程 [ppid] = %dn",getpid(),getppid());exit(0);} else if (pid > 0) {printf("我是父线程,我先退出一步~n");exit(0);}return 0;
}
复制代码

执行并看结果:

到这里估计很多童鞋估计已经看懂了,父进程退出后,子进程被一个进程ID为1的进程领养的。还挺好这个结果,至少还是有人管的,被暖到了~ 进程id为1的进程是init进程,每当有孤儿进程出现时,init进程就会收养它并成为它的父进程 ,来照顾它以孤儿进程以后的生活。

危害

因为孤儿进程会被init进程接管,所以孤儿进程是没有危害的。

僵尸进程

和孤儿进程相反的是,这次是子进程先退出,而父进程又没有去处理回收释放子进程的资源,这个时候子进程就成了僵尸进程。

先准备好代码:

[root@iz2ze76ybn73dvwmdij06zz ~]# cat zombie.c#include <stdio.h>#include <unistd.h>#include <errno.h>#include <stdlib.h>int main(){pid_t pid;pid = fork();if (pid < 0){perror("fork error:");exit(1);}else if (pid == 0){printf("我是子进程,我要先退出一步了.n");printf("子进程 id : %dn" ,getpid());exit(0);} else {printf("我是父进程,我先睡2秒n");printf("父进程 id : %dn" ,getpid());sleep(2);while(2); //来个死循环,不退出的那种}return 0;}
复制代码

运行看下结果:

再来开一个终端看下进程结果:

大家可以看到,子进程并没有完全退出,释放资源,而是变成了僵尸进程。

危害

资源上是占用不了什么资源。但是通常系统的进程数量都是有限制的,如果有大量的僵尸进程占用进程号,导致新的进程无法创建,这个危害类似于占个坑,不办事,别人也办不了事。

处理

1.干掉父进程

干掉父进程后,让剩下的子进程成为孤儿进程,成为孤儿进程后就和我们上面说的一样了,由init进程来领养这些进程,并且来处理这些进程的资源释放等工作。

2.父进程调用wait或waitpid

等函数等待子进程结束,这会导致父进程挂起。 执行wait()或 waitpid()系统调用,则子进程在终止后会立即把它在进程表中的数据返回给父进程,此时系统会立即删除该进入点。在这种情形下就不会产生defunct进程。

3.fork两次

第一次 fork : 父进程fork一个子进程

第二次 fork : 子进程fork一个孙进程后退出

那么孙进程被init接管,当孙进程结束后,init会回收。

但子进程的回收还要自己做。

4.signal函数

父进程来处理:用signal函数为SIGCHLD安装handler,在子进程结束后,父进程会收到该信号,可以在handler中调用wait回收。

内核来处理: 如果父进程不关心子进程什么时候结束,可以通过以下两个函数通知内核自己不感兴趣子进程的结束,此时,子进程结束后,内核会回收并不再给你父进程发信号。

  • signal(SIGCLD, SIG_IGN)
  • signal(SIGCHLD, SIG_IGN)

总结

本来以为简单的一个问题,没想到这个篇幅其实也不算短,所以感觉程序员真的不能说一个什么知识点就简单,很容易理解啊,一旦你想要深入也是需要一定的时间花费和精力的~

delphi pid判断进程结束_有两个这样的进程:僵尸进程amp;孤儿进程,蓝瘦香菇相关推荐

  1. python判断线程结束_判断Threading.start新线程是否执行完毕的实例

    新写自己的Threading类 class MyThread(threading.Thread):#我的Thread类 判断流程结束没 用于os shell命令是否执行判断 def __init__( ...

  2. 启动进程 问号_有两个这样的进程:僵尸进程amp;孤儿进程,蓝瘦香菇

    进程 先来说下什么是进程: 来看下百度是怎么说的: 光看说的不够形象,在windows系统中,它长这样: 在Mac系统中,它长这样: Linux中是这样的:(有点长截图一部分好了) [root@iz2 ...

  3. 34 进程 pid ppid 并发与并行,阻塞与非阻塞 join函数 process对象 孤儿进程与僵尸进程...

    进程与程序 一个正在被运行的程序就称之为进程,是程序具体执行过程,一种抽象概念 进程来自于操作系统 多进程:多个正在运行的程序. 测试: import timewhile True: time.sle ...

  4. 有两个这样的进程:僵尸进程孤儿进程,蓝瘦香菇

    程序员的成长之路 互联网/程序员/技术/资料共享 关注 阅读本文大概需要 5.8 分钟. 来自:https://juejin.im/post/5f20fbeae51d45348675fa78 那时刚写 ...

  5. linux基础知识——僵尸进城和孤儿进程

    1.什么是孤儿进程? \qquad父进程先于子进程结束,则子进程成为孤儿进程.父进程结束后,子进程的父进程由init进程接替. #include<stdio.h> #include< ...

  6. 转:Python 主进程被杀死时,如何保证子进程同时退出而不变为孤儿进程

    发布于博客园,作者:Tourun <主进程被杀死时,如何保证子进程同时退出,而不变为孤儿进程(一)> <主进程被杀死时,如何保证子进程同时退出,而不变为孤儿进程(二)> < ...

  7. delphi pid判断进程结束_PHP7是如何实现多进程的?

    我们都知道PHP是单进程执行的,PHP处理多并发主要是依赖服务器或PHP-FPM的多进程及它们进程的复用,但PHP实现多进程也意义重大,尤其是在后台Cli模式下处理大量数据或运行后台DEMON守护进程 ...

  8. qprocess start怎么判断是否结束_怎么样判断两个IP地址是否在同一个网段

    怎么样判断两个IP地址是否在同一个网段 方法 通过自身的IP与自身掩码算出网络地址X 通过目的IP与自身掩码算出目的地的网络地址Y 如果这两个网络一样(X=Y),则表示目的地与自身在一个网络内 如果两 ...

  9. qprocess start怎么判断是否结束_面试结束后,如何判断自己是否有戏?看有无这8大信号!...

    关注"职场沉浮宝典",每天get一个职场小技巧 面试结束后,在等待最终结果的过程中,我们常常会惴惴不安,喜欢在脑海里回放全部面试细节,多角度去判断自己通过面试的可能性.毕竟,面试就 ...

最新文章

  1. 存储引擎 K/V 分离下的index回写问题
  2. 在controller中无法通过注解@Value获取到配置文件中定义的值解决办法
  3. ==和equals()的区别
  4. 浅谈测试驱动开发(TDD)
  5. MFC改变对话框背景图片实例
  6. 训练日志 2019.1.24
  7. rel=nofollow
  8. 自动化系统计算机网络期末考试题,模拟试卷_计算机网络试题B-自动化-孙璐
  9. jvm maxgcpausemillis 默认值_Tomcat和JVM的性能调优总结
  10. [Python學習筆記] 使用xlwings 插入註解 (forked 版本)
  11. git cherry-pick合并某个commit
  12. 中望cad2012专业破解版
  13. 日语 敬体 简体 作文 对话
  14. 实习日记 08/23 day33 理解JVM---Java核心卷中的并发
  15. 副高级职称的要求真的很难达到吗?
  16. 正则表达式,和python re模块
  17. Python破解压缩包密码
  18. 裸金属服务器启动之PXE与IPXE实践
  19. scala在idea中的配置
  20. 【Unity】NGUI/UGUI 小地图制作

热门文章

  1. CyclicBarrier多线程
  2. Java连Mysql数据库
  3. 二、Sql Server 基础培训《进度2-关于主键(知识点学习)》
  4. python2和3搭建,pip2和pip3的安装
  5. Newtonsoft 反序列化字符串
  6. Eclipse启动Tomcat时,45秒超时解决方案
  7. KB954430补丁重复安装失败的解决办法
  8. JS SDK的标准创建原则
  9. 上有程序员删库跑路,这次是程序员锁死服务器,600万打水漂,创始人负债数百万!
  10. java好的代码_做java软件工程师,怎样才能写出好的代码?