gpt4 book ai didi

c - 如何通过流程粘合系统?

转载 作者:太空宇宙 更新时间:2023-11-04 10:31:02 24 4
gpt4 key购买 nike

关于我的程序功能的一般性和解释

我写了一个程序,其目的是创建进程,直到它不能再这样做(id est:它必须粘合操作系统并完全填充进程表)。但是,当 OS 被粘住时,会出现类似“fork can't be done anymore”的消息,最终用户可以通过 CTRL+ 杀死所有进程Z.

我的程序包含两个重要进程:主要进程创建第二个进程。第一个在我的代码中称为“MAIN_P”,后者称为“P_ROOT”。 P_ROOT 的目标是 fork 直到他不能再做为止。当出现 fork 错误时(id est:当我的程序成功时!),最终用户可以向 MAIN_P 发送 CTRL-Z 信号,这将杀死 P_ROOT 及其 children 。

我明确指出 P_ROOT 及其子项具有相同的 GPID(继承)。但后者当然不同于 MAIN_P 的(setsid 应用于 P_ROOT)。


我的问题

当我启动我的程序时,它fork第一个子进程,它fork它的子进程直到操作系统被粘合(即:直到进程表被完全填满) .唯一的问题是我不能在我的控制台中 CTRL + Z 来停止它......当然,如果我只是退出终端,它不会杀死所有这些进程(并且其他进程继续被 fork )。

因此,我不建议你执行它......

我的代码有什么问题?


来源

#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
}

最佳答案

评论:

  • 要快速达到 fork() 限制,您必须确保每个派生进程不会消耗太多资源。您的 fork 进程在 for 循环中旋转并占用了太多资源。如果删除 for 循环,您将更快地达到进程限制,因为进程将在 sleep() 调用而不是旋转时被阻塞。
  • 在 fork() 错误之后,您不需要等待循环来等待进程完成。这将自动发生。

更新的来源:

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>

int main(int argc, char* argv[]) {
// This (first !) child, say "P_ROOT", will create its own children, which will glue the system (thus, MAIN_P is freed
int p_root = fork();
if(p_root == -1) {
perror("fork");
exit(EXIT_FAILURE);
}
// P_ROOT's PGID will be set to its PID (so we have : P_ROOT's PGID != MAIN_P's PGID)
if (p_root == 0) {
if(setpgid(p_root, p_root) == -1) {
perror("setpgid");
exit(EXIT_FAILURE);
}

int p_root_number_of_created_children = 0;
pid_t p_root_child = 0;
while((p_root_child = fork()) != -1) { // P_ROOT forks until it can't do it anymore...
if(p_root_child != 0) {
p_root_number_of_created_children++;
} else {
#ifdef CONSUME_RESOURCES
int i = 0;
while(i < 1000000000000000000) {
i++;
}
#endif
sleep(6000);
exit(EXIT_FAILURE);
}
}

// NOW it's impossible to create new child processes
perror("fork");
fprintf(stdout, "\nImpossible to create more children. Their number is : %d\n", p_root_number_of_created_children);
exit(EXIT_SUCCESS);
} else {
printf("Waiting, top level, root = %d\n", p_root);
wait(NULL); // MAIN_P waits for P_ROOT

char cmd = 0;

if(scanf("%c", &cmd) < 0) {
perror("scanf");
exit(EXIT_FAILURE);
}

if(cmd == '\n' && kill(-p_root, SIGKILL) == -1) {
perror("kill");
exit(EXIT_FAILURE);
}

exit(EXIT_SUCCESS);
}
}

关于c - 如何通过流程粘合系统?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39923309/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com