我的C类包含实现一个非常小的shell。
我们的shell检查用户的输入行中是否有内部命令(例如cd或exit),如果找不到,则将fork()和execs()输入行。
我希望实现一个简单的分叉(这超出了本堂课的职责范围,请不要让我自己做作业,这更多是个人研究,目的是为了了解更多有关Linux内部的知识) 。我当前的方法是这样的:
t = fork();
if (t < 0) {
if (errno == ENOSYS) {
printf("fork() is not supported on this platform. Minishell will not work.");
break;
}
else if (errno == ENOMEM) {
printf("No free kernel memory. Minishell will exit.");
break;
}
else {
int try = 0;
while (t < 0 && try < 10) {
try++;
t = fork();
}
}
continue;
}
我的理解是ENOSYS不允许分叉,因此我们退出了,因为ENOMEM表示内核内存有问题-超出了我的薪水范围(我没有付款,我是学生;)),因此我们也退出了。保留EAGAIN,它有两种形式,可以通过再次等待并调用fork()来解决。
在上一个练习中,我们启动了1万次派生,如果我没记错的话,大约有1500次失败,直到我们像上面的时候那样实现了一个计数器。如果我想以一种不太幼稚的方式实现此东西,该怎么办?我想,特别是硬编码的十次尝试有点愚蠢。
谢谢。
我认为您当前的重试方法是误解了EAGAIN错误的含义。从Linux手册页:
EAGAIN fork()无法分配足够的内存来复制父级的页表并为子级分配任务结构。
EAGAIN无法创建新进程,因为遇到了调用者的RLIMIT_NPROC资源限制。要超过此限制,该进程必须具有CAP_SYS_ADMIN或CAP_SYS_RESOURCE能力。
第一个与ENOMEM相当,第二个是达到过程上限的问题。除非您希望微型外壳始终使子进程死亡,否则快速连续尝试10次可能无济于事。
我建议您也将EAGAIN变成您的fork代码的致命错误。
但是,如果您的程序可以采取某些措施来减轻内存压力(释放程序缓存等),则可以执行此操作,然后重试一次。
值得一提的是,在正常负载下,任何现代系统上几乎都不存在会导致分叉失败的条件。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句