linux mysql 僵尸进程_Linux 系统中僵尸进程
Linux 系统中僵尸进程和现实中僵尸(虽然我也没见过)类似,虽然已经死了,但是由于没人给它们收尸,还能四处走动。僵尸进程指的是那些虽然已经终止的进程,但仍然保留一些信息,等待其父进程为其收尸。
僵尸进程如何产生的?
如果一个进程在其终止的时候,自己就回收所有分配给它的资源,系统就不会产生所谓的僵尸进程了。那么我们说一个进程终止之后,还保留哪些信息?为什么终止之后还需要保留这些信息呢?
一个进程终止的方法很多,进程终止后有些信息对于父进程和内核还是很有用的,例如进程的 ID号、进程的退出状态、进程运行的CPU时间等。因此进程在终止时,回收所有内核分配给它的内存、关闭它打开的所有文件等等,但是还会保留以上极少的信 息,以供父进程使用。父进程可以使用 wait/waitpid 等系统调用来为子进程收拾,做一些收尾工作。
因此,一个僵尸进程产生的过程是:父进程调用fork创建子进程后,子进程运行直至其终止,它立即从内存中移除,但进程描述符仍然保留在内存中(进程描述符占有极少的内存空间)。子进程的状态变成EXIT_ZOMBIE,并且向父进程发送SIGCHLD 信号,父进程此时应该调用 wait() 系 统调用来获取子进程的退出状态以及其它的信息。在 wait 调用之后,僵尸进程就完全从内存中移除。因此一个僵尸存在于其终止到父进程调用 wait 等函数这个时间的间隙,一般很快就消失,但如果编程不合理,父进程从不调用 wait 等系统调用来收集僵尸进程,那么这些进程会一直存在内存中。
在 Linux 下,我们可以使用 ps 等命令查看系统中僵尸进程,僵尸进程的状态标记为‘Z’:
产生一个僵尸进程
根据上面的描述,我们很容易去写一个程序来产生僵尸进程,如下代码:
#include
#include
int main()
{
//fork a child process
pid_t pid = fork();
if (pid > 0) //parent process
{
printf("in parent process, sleep for one miniute...zZ...n");
sleep(60);
printf("after sleeping, and exit!n");
}
else if (pid == 0)
{
//child process exit, and to be a zombie process
printf("in child process, and exit!n");
exit(0);
}
return 0;
}
父进程并没有写 wait 等系统调用函数,因此在子进程退出之后变成僵尸进程,父进程并没有为其去收尸。我们使用下面命令编译运行该进程,然后查看系统中进程状态:
guohailin@guohailin:~/Documents$ gcc zombie.c -o zombie
guohailin@guohailin:~/Documents$ ./zombie
in parent process, sleep for one miniute...zZ...
in child process, and exit!
# 打开另一个终端:
guohailin@guohailin:~$ ps aux | grep -w 'Z'
1000 2211 1.2 0.0 0 0 ? Z 13:24 6:53 [chromium-browse]
1000 4400 0.0 0.0 0 0 ? Z 10月16 0:00 [fcitx]
1000 10871 0.0 0.0 0 0 pts/4 Z+ 22:32 0:00 [zombie]
从上面可以看出,系统中多了一个僵尸进程。但如果等父进程睡眠醒来退出之后,我们再次查看系统进程信息,发现刚才的僵尸进程不见了。
guohailin@guohailin:~/Documents$ ./zombie
in parent process, sleep for one miniute...zZ...
in child process, and exit!
after sleeping, and exit!
guohailin@guohailin:~/Documents$ ps aux | grep -w 'Z'
1000 2211 1.2 0.0 0 0 ? Z 13:24 6:53 [chromium-browse]
1000 4400 0.0 0.0 0 0 ? Z 10月16 0:00 [fcitx]
这是为什么呢?父进程到死都也没有为其子进程收尸呀,怎么父进程退出之后,那个僵尸进程 就消失了呢?难道父进程在退出时会为子进程收拾吗?其实不然….真正的原因是:父进程死掉之后,其所有子进程过继给 init 进程,init 进程成为该僵尸进程的新进程,init 进程会周期性地去调用 wait 系统调用来清除它的僵尸孩子。因此,你会发现上面例子中父进程死掉之后,僵尸进程也跟着消失,其实是 init 进程为其收尸的!
怎样避免僵尸进程的产生
不能使用 kill 后接 SIGKILL 信号这样的命令像杀死普通进程一样杀死僵尸进程,因为僵尸进程是已经死掉的进程,它不能再接收任何信号。事实上,如果系统中僵尸进程并不多的话,我们也无需去消除它们,少数的僵尸进程并不会对系统的性能有什么影响。
那么在编程时,如果能避免系统中大量产生僵尸进程呢?根据上面描述的,子进程在终止时会 向父进程发 SIGCHLD 信号,Linux 默认是忽略该信号的,我们可以显示安装该信号,在信号处理函数中调用 wait 等函数来为其收尸,这样就能避免僵尸进程长期存在于系统中了。示例代码如下:
#include
#include
#include
#include
#include
sig_atomic_t child_exit_status;
void clean_up_child_process(int signal_num)
{
/* clean up child process */
int status;
wait (&status);
/* store its exit status in a global variable */
child_exit_status = status;
}
int main()
{
/* handle SIGCHLD by calling clean_up_child_process */
struct sigaction sigchild_action;
memset(&sigchild_action, 0, sizeof(sigchild_action));
sigchild_action.sa_handler = &clean_up_child_process;
sigaction(SIGCHLD, &sigchild_action, NULL);
/* fork a child, and let the child process dies before parent */
pid_t c_pid;
c_pid = fork();
if (c_pid > 0)
{
printf("in parent process, and sleep for on mininute...zZ...n");
sleep(60);
}
else if(c_pid == 0)
{
printf("in child process, and exit nown");
exit(0);
}
else
{
printf("fork failed!n");
}
return 0;
}
linux mysql 僵尸进程_Linux 系统中僵尸进程相关推荐
- linux java 僵尸进程_Linux 系统中僵尸进程
Linux 系统中僵尸进程和现实中僵尸(虽然我也没见过)类似,虽然已经死了,但是由于没人给它们收尸,还能四处走动.僵尸进程指的是那些虽然已经终止的进程,但仍然保留一些信息,等待其父进程为其收尸.配图源 ...
- linux mysql 测试工具_LINUX系统下MySQL 压力测试工具super smack
LINUX系统下MySQL 压力测试工具super smack 发布时间:2008-09-08 17:03:39 作者:佚名 我要评论 1. 源文件下载地址:http://vegan.net/ ...
- linux+mysql+导出备份_Linux系统MySQL备份的导入导出的具体分析
问题描述 如何对 ECS Linux 系统中的 MySQL 进行备份的导入和导出. 处理办法MySQL 备份的导出 MySQL 备份的导入 MySQL 备份的导出 注意:如果您使用的是帮助中心的一键环 ...
- jdb2 mysql io_CentOS 6.4系统中jdb2进程占用io过高的解决方法
某日在检测一系统性能时,发现io性能总是无故被消耗,即使应用程序很空闲,io使用程度也 很高. 使用iotop工具查看io情况. Total DISK READ: 0.00 B/s | Total D ...
- linux ftp下载文件_Linux系统中10个使用Wget命令下载文件示例
wget 是一个从网络上自动下载文件的命令行工具,支持通过 HTTP.HTTPS.FTP 三个最常见的 TCP/IP协议 下载,并可以使用 HTTP 代理.它是一个非交互式工具,非常适合通过脚本或者在 ...
- linux mutt安装配置_Linux系统中安装配置Mutt来作为Gmail客户端
mutt是一个Linux终端下的著名的邮件客户端,如你所愿,mutt就是一个邮件客户端.没有其他浮华的功能,它可以帮助你提升效率,至于帮助你装X只能算是mutt的特殊加成. 由于mutt是一个有着un ...
- linux mysql 查看索引_linux系统mysql索引
索引 一.索引的分类 1.根据算法分类 1)主键索引 #1.建表时创建 create table test(id int primary key); create table test(id int, ...
- linux mysql 端口配置文件_linux虚拟机中各服务端口及配置文件路径
查询端口状况命令: netstat -an| grep 端口号 查询服务状态(服务是否开启)命令:systemctl status 服务名 开启服务命令:systemctl start 服务名 ...
- linux mysql 创建存储过程_linux系统下无法创建mysql存储过程问题
创建存储过程的完整命令: CREATE PROCEDURE pro1() begin declare b int default 0; end; mysql中运行存储过程创建语句错误结果: root@ ...
最新文章
- UI设计师培训入门都需要学习什么技术?
- 马云打响本地生活消费攻坚战,饿了么获手淘一级入口,美团危险了
- 饭卡(HDOJ2546)
- 在集群环境中安装sql2005的sp2
- 数据结构与算法笔记(十五)—— 散列(哈希表)
- HTTP 状态代码及其定义(转载)
- 1.6-1.7配置IP1.8网络问题排查
- kibana安装与Kibana server is not ready yet
- mockjs中的方法(三)
- (设计模式之一)浅析简单工厂模式
- 邹博机器学习代码分析(1)-线性回归
- BI解决方案分享:地产BI数据分析系统的建设
- CF 1383/1384
- 哈夫曼树(huffman)
- 怎么样将Excel数据中的小数提取出来
- 网络编程--JAVA之多线程下载后续:断点续存
- OrangePi PC 玩Linux主线内核踩坑之旅(二)之制作镜像后的查遗补缺
- 什么是美颜SDK?怎样选择美颜SDK?
- 第一次暑假实习面试,进入二面就算成功(没有成功)
- 4核服务器型号,服务器厂商、型号、参数。
热门文章
- PCL1.9.1下载与配置+Visual Studio2017
- sublime的注册方法 非常好用
- Spring Boot进阶(13):如何获取@ApiModelProperty(value = “序列号“, name = “uuid“)中的value值 | 超级详细,建议收藏
- mysql fastdfs_FastDFS监控系统Fastdfs-zyc配置
- 【技术贴】解决打开程序出错,提示错误429,activex部件不能创建对象,不用重装系统。...
- 开水果店的水果怎么保鲜,新手开水果店水果保鲜方法
- Java餐饮酒店管理系统PC端,使用SpringBoot、Layer,Beetl
- 如何租用虚拟服务器,怎么租用虚拟主机
- 智能硬件开发如何选择低功耗MCU?
- Delphi TreeView树型框节点拖拽停靠、按条件开始拖拽