**Linux 知识补充 -- 守护进程的编写及使用方法 - 04 守护进程再次分裂子进程** 1652270 **冯舜** ## 写 `test5-1.c` 编辑 `test5-1.c` 的内容: ~~~~~~~~~~~~~C ~~~~~~~~~~~~~ 加参数 `-std=c99` 编译运行之. ## 极限测试分裂进程的最大数量 ### 当虚拟机内存为 512 MB 时 当虚拟机内存为 512 MB 时, 最多分裂 3388 个子进程, 如//5512//. !![5512,虚拟机内存为 512 MB] ### 当虚拟机内存为 1024 MB 时 当虚拟机内存为 1024 MB 时, 最多分裂 7423 个子进程, 如//51024//. !![51024,虚拟机内存为 1024 MB] ### 当虚拟机内存为 2048 MB 时 当虚拟机内存为 2048 MB 时, 最多分裂 14201 个子进程, 如//52048//. !![52048,虚拟机内存为 2048 MB] ## 在每子进程数据空间占用 10 倍时, 分裂进程的最大数量. 将每个子进程开的字符数组大小常量 `strsiz` 扩大十倍后, 另存为 `test5-1-10.c`, 编译运行. ### 当虚拟机内存为 512 MB 时 当虚拟机内存为 512 MB 时, 最多分裂 3388 个子进程, 如//55122//. !![55122,虚拟机内存为 512 MB] ### 当虚拟机内存为 1024 MB 时 当虚拟机内存为 1024 MB 时, 最多分裂 7376 个子进程, 如//510242//. !![510242,虚拟机内存为 1024 MB] ### 当虚拟机内存为 2048 MB 时 当虚拟机内存为 2048 MB 时, 最多分裂 14203 个子进程, 如//520482//. !![520482,虚拟机内存为 2048 MB] 可以发现, 即使每进程数据空间扩大十倍, 可分裂进程数基本不变, 所以系统允许最大进程数仅与内存大小有关. ## 使用等待方法分裂完成指定数量的大进程 编辑 `test5-2.c` 的内容, 以能够用等待其他进程结束再分裂的方式, 使得能够继续分裂下去以至分裂完成指定数量的大进程. 为了加快执行速度, 取消对数据数组的随机赋值, 而是全部只赋同一个值 `'a'`. 分裂子进程失败的根本原因是达到了进程数量上限. 当 `fork()` 的返回值为失败时, 执行 `wait()` 函数, 等待有子进程执行完成后再次尝试分裂. ~~~~~~~~~~~~~C ~~~~~~~~~~~~~ 在 512 MB 的虚拟机上运行程序, 最终正常分裂完成 100000 个子进程. 如//5512full//. !![5512full,正常分裂 100000 个子进程] 分裂完成等其他子进程退出后, 使用 `ps -ef|grep test` 查询有关进程, 发现子进程都已退出, 只剩父进程, 如//5512afterfull//. !![5512afterfull,分裂完成后, 只剩下父进程] ## 分裂子进程的最大进程号 运行 `test5-2 200000`. 发现 PID 从 9000 多开始计算. 但到了 131071 后, PID 号不再增长. 运行完成后如//5512maxfull//. 在结束进入死循环后, 用 `ps -ef|grep test` 查看所有相关进程, 发现 PID 到了最大值后, 新生成子进程的 PID 回归较小的值. 如//5512aftermaxfull//. !![5512maxfull,PID 号到了 131071 不再增长] !![5512aftermaxfull,PID 号在达到最大值后, 从小值开始] ## 生成计数器和回收计数器 编辑 `test5-3.c`. 在其中, 不再使用 `wait()` 函数作为子进程分裂失败时的措施, 而改为 `sleep(5)` 等待; 捕获 `SIGCHLD` 信号, 在处理函数中循环处理所有到达的子进程死亡信息, 每次对计数器加 1. ~~~~~~~~~~~~~~~~~~~~~C ~~~~~~~~~~~~~~~~~~~~~ 编译并在 2048 MB 的虚拟机上运行程序: `./test5-3 100000`. 运行完成后, 如//52048recycle//, 生成计数器和回收计数器的值相等, 并且用 `ps -ef|grep test` 查看之后, 除父进程外没有僵尸子进程 (未体现在图中). !![52048recycle,2048 MB 虚拟机统计生成计数器和回收计数器]