孤儿进程与僵尸进程

孤儿进程:

如果父进程先退出,子进程还没退出那么子进程的父进程将变为init进程。(注:任何一个进程都必须有父进程)

//生成孤儿进程
int main(int argc, char *argv[])
{pid_t pid = fork();if (pid < 0)err_exit("fork error");else if (pid > 0)exit(0);else{sleep(10);cout << "Child, ppid = " << getppid() << endl;}exit(0);
}

僵尸进程:

如果子进程先退出,父进程还没退出,那么子进程必须等到父进程捕获到了子进程的退出状态才真正结束,否则这个时候子进程就成为僵尸进程。

//生成僵尸进程
int main(int argc, char *argv[])
{pid_t pid = fork();if (pid < 0)err_exit("fork error");else if (pid == 0)exit(0);else{sleep(50);}exit(0);
}

-查询父子进程状态

ps -le | grep main

避免僵尸进程

signal(SIGCHLD, SIG_IGN);

//示例: 避免僵尸进程
int main(int argc, char *argv[])
{signal(SIGCHLD, SIG_IGN);pid_t pid = fork();if (pid < 0)err_exit("fork error");else if (pid == 0)exit(0);else{sleep(50);}exit(0);
}

文件共享

父进程的所有文件描述符都被复制到子进程中, 就好像调用了dup函数, 父进程和子进程每个相同的打开文件描述符共享一个文件表项(因此, 父子进程共享同一个文件偏移量);

//根据上图: 理解下面这段程序和下图的演示
int main(int argc, char *argv[])
{signal(SIGCHLD, SIG_IGN);int fd = open("test.txt", O_WRONLY|O_CREAT|O_TRUNC, 0666);if (fd == -1)err_exit("file open error");cout << "We Don`t flash memory\n";char buf[BUFSIZ];bzero(buf, sizeof(buf));pid_t pid = fork();if (pid < 0)err_exit("fork error");else if (pid > 0){strcpy(buf, "Parent...");write(fd, buf, strlen(buf));close(fd);cout << "fd = " << fd << endl;exit(0);}else if (pid == 0){strcpy(buf, "Child...");write(fd, buf, strlen(buf));close(fd);cout << "fd = " << fd << endl;exit(0);}
}

fork VS vfork

在UNIX/Linux中的fork还没实现copy on write(写时复制)技术之前。Unix设计者很关心fork之后立刻执行exec所造成的地址空间浪费,所以引入了vfork系统调用。其中,vfork子进程与父进程共享数据段,并不真正复制父进程内存,因此在vfork之后执行exec系列函数,并不会导致地址空间浪费以及无用的空间复制时间.而且,即使fork实现了copy on write,效率也没有vfork高.

但是,vfork有个限制,子进程必须立刻执行_exit或者exec系列函数。因此我们不推荐使用vfork,因为几乎每一个vfork的实现,都或多或少存在一定的问题(可以尝试在vfork之后的子进程中既不执行_exit,也不执行exec函数)。

fork与vfork的区别

1. fork子进程拷贝父进程的数据段(但是现在提供了写时复制技术,只有当子进程真正需要写内存时,才复制出该内存的一段副本),因此,在父进程/子进程中对全局变量所做的修改并不会影响子进程/父进程的数据内容.

vfork子进程与父进程共享数据段,因此父子进程对数据的更新是同步的;

2. fork父、子进程的执行次序是未知的,取决于操作系统的调度算法

vfork:子进程先运行,父进程后运行;

//示例1:vfork出错情况
//在Linux 2.6内核上会持续执行,不会退出
//而在Linux 3.13内核上, 则会引发core dump
int main()
{int iNumber = 0;pid_t pid = vfork();if (pid == -1){perror("fork");return -1;}else if (pid > 0){cout << "In Parent Program..." << endl;cout << "iNumber = " << iNumber << endl;cout << "pid = " << static_cast<int>(getpid());cout << "\t ppid = " << static_cast<int>(getppid()) << endl;//_exit(0);}else if (pid == 0){iNumber ++;cout << "In Child Program..." << endl;cout << "iNumber = " << iNumber << endl;cout << "pid = " << static_cast<int>(getpid());cout << "\t ppid = " << static_cast<int>(getppid()) << endl;//_exit(0);}return 0;
}

//示例2: 父进程/子进程修改全局数据的情况
int main()
{int iNumber = 10;cout << "Before vfork, pid = " << getpid() << endl;//对比fork()pid_t pid = vfork();if (pid == -1)err_exit("fork");else if (pid > 0){sleep(4);cout << "Parent, iNumber: " << iNumber << endl;}else if (pid == 0){++ iNumber;cout << "Child, iNumber = " << iNumber << endl;_exit(0);}return 0;
}
//示例3:用vfork执行当前目录下的hello程序
int main()
{int iNumber = 0;pid_t pid = vfork();if (pid == -1){perror("fork");return -1;}else if (pid > 0){cout << "In Parent Program..." << endl;cout << "iNumber = " << iNumber << endl;cout << "pid = " << static_cast<int>(getpid());cout << "\t ppid = " << static_cast<int>(getppid()) << endl;}else if (pid == 0){iNumber ++;cout << "In Child Program..." << endl;cout << "iNumber = " << iNumber << endl;cout << "pid = " << static_cast<int>(getpid());cout << "\t ppid = " << static_cast<int>(getppid()) << endl;//将自己写的程序启动起来execve("./hello",NULL,NULL);_exit(0);}return 0;
}

//测试4,用vfork执行系统命令
int main()
{int iNumber = 0;pid_t pid = vfork();if (pid == -1){perror("fork");return -1;}else if (pid > 0){cout << "In Parent Program..." << endl;cout << "iNumber = " << iNumber << endl;cout << "pid = " << static_cast<int>(getpid());cout << "\t ppid = " << static_cast<int>(getppid()) << endl;}else if (pid == 0){iNumber ++;cout << "In Child Program..." << endl;cout << "iNumber = " << iNumber << endl;cout << "pid = " << static_cast<int>(getpid());cout << "\t ppid = " << static_cast<int>(getppid()) << endl;//将ls命令启动起来,注意:由于C++严格的类型转换机制,需要在字符串前加(char*)char *const args[] = {(char *)"/bin/ls", (char *)"-l", NULL};int res = execve("/bin/ls",args,NULL);if (res == -1){perror("execve");_exit(1);}_exit(0);}return 0;
}

Linux进程实践(2) --僵尸进程与文件共享相关推荐

  1. linux shell中清理僵尸进程

    2019独角兽企业重金招聘Python工程师标准>>> 今天登录到服务器上时,系统打印有6 zombie processes存在,于是用kill -9去清理掉这些僵尸进程,命令执行完 ...

  2. linux僵尸进程理解,聊聊Linux系统中的僵尸进程

    车祸现场 今天下午,笔者正在认真搬砖,日志集群中有一台机器忽然报init进程占用100% CPU.strace之,发现疯狂输出如下系统调用. ~ strace -p 1 rt_sigprocmask( ...

  3. Linux查找并杀死僵尸进程

    1.查看系统是否有僵尸进程 使用Top命令查找,当zombie前的数量不为0时,即系统内存在相应数量的僵尸进程. 2.定位僵尸进程 使用命令ps -A -ostat,ppid,pid,cmd |gre ...

  4. JAVA项目linux僵尸进程_linux杀死僵尸进程

    ps -A -o stat,ppid,pid,cmd | grep -e '^[Zz]' | awk '{print $2}' | xargs kill -9 1.查看系统是否有僵尸进程 使用Top命 ...

  5. 【k8s】理解Docker容器的进程管理(PID1进程(容器内kill命令无法杀死)、进程信号处理、僵尸进程)

    文章目录 概述 1. 容器的PID namespace(名空间) 2. 如何指明容器PID1进程 3. 进程信号处理 4. 孤儿进程与僵尸进程管理 5. 进程监控 6. 总结 参考 概述 简介: Do ...

  6. linux里面有mysql的僵尸进程_Linux的僵尸进程处理1

    Linux中有两种异常的进程: 1.孤儿进程:应用通过fork进程后,父进程被kill或者exit,该父进程的子进程被1号进程接管.linux内核启动时候回启动0号进程,启动完毕后0号进程就处于空闲状 ...

  7. 【Linux进程、线程、任务调度】一 Linux进程生命周期 僵尸进程的含义 停止状态与作业控制 内存泄漏的真实含义 task_struct以及task_struct之间的关系

    学习交流加(可免费帮忙下载CSDN资源): 个人微信: liu1126137994 学习交流资源分享qq群1(已满): 962535112 学习交流资源分享qq群2: 780902027 文章目录 1 ...

  8. 1进程 ppid_杀死僵尸进程,你需要这些神奇的Linux命令行

    Linux高手,其实都是玩儿命令行很熟练的人. 命令行的学习捷径 Linux命令有许多强大的功能:从简单的磁盘操作.文件存取,到进行复杂的多媒体图像和流媒体文件的制作,都离不开命令行. 在Linux的 ...

  9. 总结-linux初识进程(包括cpu调度、进程创建、僵尸进程(重点)、环境变量)

    冯诺依曼体系结构--现代计算机的硬件体系结构 输入设备.输出设备(数据输出).存储器(数据缓冲).运算器(数据运算).控制器. 所有设备都是围绕存储器工作---CPU是从存储器中获取数据处理---控制 ...

最新文章

  1. 某程序员吐槽自己追求某字节HR,暧昧半年,见面后却被告知是普通朋友!心态已崩!网友:别追HR!道行太深!...
  2. android xml 文件里面的宽度Match_Parent 被 替换成了wrap_content
  3. MF RC522读卡芯片手册
  4. Leetcode738. 单调递增的数字[C++题解]:贪心,数学解法
  5. HBuilderX代码设置断点或者书签
  6. UGUI_使用DoTween
  7. Java动态代理生成的对象导出方法
  8. Java并发:隐藏线程死锁
  9. C#中使用多线程访问Winform问题解决方案
  10. 开发者都应该使用的10个C++11特性
  11. python画两条曲线_python – 在Matplotlib中绘制两个图之间的线
  12. PHP PDO学习(二) exec执行SQL
  13. 拓端tecdat|R语言对BRFSS数据探索回归数据分析
  14. mysql tx read only_DB为何大量出现select @@session.tx_read_only 详解
  15. D-Bus 性能分析
  16. EtherCAT:wireshark抓包分析
  17. 想网站与目标站点同步更新?利用采集侠轻松实现
  18. 四川大学转专业到计算机学院面试,2016年本科生转专业工作面试通知
  19. 人生如游戏,容错性很关键
  20. TCP全连接端口扫描器

热门文章

  1. (王道408考研操作系统)第二章进程管理-第一节1:进程、PCB及其特征
  2. Kali Linux中的VEIL Framework绕过防病毒软件实验
  3. js数组往队头添加数据、js数组从队头移出数据
  4. Python 爬虫学习笔记
  5. Android深度探索(卷1)HAL与驱动开发 心得体会 第十章 嵌入式Linux的调用技术
  6. CocoaPods pod install
  7. OpenLayers相关资料
  8. Apache设置文件缓存时间
  9. win7重置密码的方法
  10. 设计模式学习之单件模式singleton