【发布时间】:2016-10-07 17:59:16
【问题描述】:
关于我的程序功能的一般性和解释
我编写了一个程序,其目的是创建进程,直到它不能再这样做(id est:它必须粘合操作系统并完全填充进程表)。但是,当 OS 被粘上时,会出现类似“fork 无法再完成”的消息,并且所有进程都可以被最终用户杀死,这要归功于 CTRL+Z.
我的程序包含两个重要的过程:主要的一个,它创建第二个。第一个在我的代码中称为“MAIN_P”,后者称为“P_ROOT”。 P_ROOT 的目标是fork,直到他做不到为止。当出现fork 错误时(id est:当我的程序成功时!),最终用户可以向 MAIN_P 发送 CTRL-Z 信号,这将杀死 P_ROOT 及其子项。
我确定 P_ROOT 及其子节点具有相同的 GPID(继承)。当然,后者与 MAIN_P 的不同(setsid 应用于 P_ROOT)。
我的问题
当我启动我的程序时,它fork 第一个孩子,fork 它的孩子直到操作系统被粘合(即:直到进程表完全填满)。唯一的问题是我无法在控制台中的 CTRL + Z 停止它......当然,如果我只是退出终端,它不会杀死所有这些进程(而且其他进程继续被分叉)。
因此,我不建议你执行它...
我的代码有什么问题?
来源
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/resource.h>
int main(int argc, char* argv[]) {
pid_t pid_first_child = 0;
if((pid_first_child = fork()) == -1) { // We `fork` the first child, which will always `fork` (more precisely : until the OS is glued, processes table completely filled)
perror("fork");
exit(EXIT_FAILURE);
}
if(pid_first_child == 0) { // BEGINNING OF <FirstChild>'S CODE
pid_t pid_session_leader = 0;
if((pid_session_leader = setsid()) == -1) { // FirstChild is its process group's leader
perror("setsid");
exit(EXIT_FAILURE);
}
if(setpriority(PRIO_PGRP, pid_session_leader, -10) == -1) { // The priority of FirstChild (which is the group's leader)
perror("setpriority");
exit(EXIT_FAILURE);
}
unsigned children_counter = 0;
pid_t pid_calculation_process = 0;
while((pid_calculation_process = fork()) != -1) { // Now, FirstChild will `fork` until the limit ! When the limit is reached, -1 is returned : there isn't anymore `fork` and we exit the loop
if(pid_calculation_process > 0) {
children_counter++;
fprintf(stdout, "%u\n", children_counter);
} else { // BEGINNING OF <FirstChild's children>'s CODE (Why ? Consequently to the `while` and the `if` !)
float j=1;
while(1) { // Children can't die
int i = 0;
for(; i < 1000; i++) {
j /= 3;
}
usleep(1000);
}
} // END OF <FirstChild's children>'s CODE (FirstChild's children)
}
perror("fork"); // It's what we wanted ! This message will tell the user "OS is glued, program worked correctly"
exit(EXIT_SUCCESS); // `EXIT_SUCCESS` ? Because we reached the limit !
} // END OF <FirstChild>'S CODE
}
【问题讨论】:
-
在运行程序之前尝试使用
ulimit -u 50设置您的进程限制。当你达到限制时,你应该得到错误。 -
提示:你的 //nota bene 没有多大意义。当人们使用“p_”具有特定含义时,dont“覆盖该含义。这样的初始 cmets 迟早会被忽略。含义:从不放置代码这可能会让读者惊喜!
-
@Barmar :实际上我不想设置进程限制。我真的很想完全填满进程表并粘合操作系统。但是,我希望能够在终端中按 CTRL + Z 杀死所有进程,从而释放进程表。
-
@GhostCat:谢谢!我完全改变了我的代码(并发现了一个新问题:我不能用 CTRL + Z 杀死进程);新的更短。我也改了名字。
-
注意:我想写 CTRL + C,而不是 CTRL + Z(抱歉,无法编辑我的评论)