【问题标题】:c program that runs itself using system使用系统自行运行的c程序
【发布时间】:2016-12-04 02:47:53
【问题描述】:

我在学习函数 system() 是 stdlib.h 并意识到我可以创建一个使用 system() 自行运行的程序。我写了这段代码并试了一下:

#include <stdio.h>
#include <stdlib.h>

int main(){
    printf("x");
    system("./a.out");
}

每次我在正常退出之前运行它时,它都会准确地打印 563 x 到控制台(没有错误)。我想知道是什么停止了程序以及这个数字来自哪里,因为这对我来说似乎很随意。谢谢

感谢您对第一个程序的见解,但我不相信系统会停止它,因为它的资源不足,原因如下:我刚刚编写了这个新程序,它还没有停止。

#include <stdio.h>
#include <stdlib.h>

int main(){
    printf("x");
    system("./a.out");
    system("./a.out");
}

另外,当我尝试打开一个新的控制台窗口时,我收到了这个错误:

/.oh-my-zsh/lib/theme-and-appearance.zsh:24: fork failed: resource temporarily unavailable

/.oh-my-zsh/oh-my-zsh.sh:57: fork failed: resource temporarily unavailable

【问题讨论】:

  • "... 我不相信系统会因为资源不足而停止它..." - "... 我得到了这个错误:fork failed: resource暂时不可用...” - 确信了吗?
  • 我想扩展一个事实,即您的第二个程序打印的 x 不应该是第一个程序的两倍 - 相反,x 的数量(和运行时)对于每次调用都会加倍 程序。所以你大概会看到2^563 x 打印到屏幕上——它永远不会停止。
  • 当你不检查 system() 调用的返回值时,你怎么知道没有错误?显然有错误,你忽略它。

标签: c


【解决方案1】:

我将首先处理第二个程序,因为它最容易解释。试试这个代码,它会打印出递归深度。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char** argv){
  int depth = argc > 1 ? atoi(argv[1]) : 0;
  printf("%d\n", depth);
  char cmd[128];
  sprintf(cmd, "%s %d", "./a.out", depth+1);
  system(cmd);
  system(cmd);
}

它会一直增长到你的极限(在我的例子中是 538),然后开始在递归树上上下颠簸。

530 531 532 533 534 535 536 537 538 538 537 538 538 536 537

这个过程最终会完成,但需要很长时间!

至于第一个节目。我相信您只是遇到了用户进程限制。

你可以通过运行找到你的进程限制

ulimit -u

在我的情况下,限制是 709。计算我运行的其他进程

ps aux | grep user | wc -l

这给了我 171. 171 + 538(我的程序死亡深度)给你一个可靠的答案:)

https://superuser.com/questions/559709/how-to-change-the-maximum-number-of-fork-process-by-user-in-linux

【讨论】:

  • 或者,简单的echo $(($(ps aux | grep user | wc -l) + $(ulimit -u)))
【解决方案2】:

您的程序中没有任何东西可以阻止无限递归。

You execute a.out.  
  a.out executes a.out  
    a.out executes a.out  
      a.out executes a.out  
        a.out executes a.out  

等等。

在某些时候,系统运行资源并且不执行下一个system 调用并且程序以相反的顺序退出。看来您的计算机在运行程序 563 次时已达到限制。

【讨论】:

  • 数字 563 是从哪里来的呢?每次都是这样。
  • @fred,限制取决于计算机、操作系统以及您执行 a.out 时正在运行的其他进程的数量。
  • 为什么操作系统现在没有耗尽资源?
  • @fred,您通过添加第二个 system 调用使程序变得更糟。让它更简单。假设计算机在 2 次调用后将不再执行 system 调用。现在尝试跟踪执行路径。您会注意到程序执行从未停止。
【解决方案3】:

要查看幕后发生的事情,请使用以下程序之一:

  • strace (Linux)
  • ktruss (Solaris)
  • ktrace (BSD)
  • 进程监视器 (Windows)

这些程序列出进程进行的所有系统调用,包括任何错误代码。

阅读他们的文档,因为从长远来看,这比我在这里给出一个用例对您的帮助更大。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-24
    • 1970-01-01
    • 2014-01-14
    • 1970-01-01
    • 1970-01-01
    • 2013-12-29
    相关资源
    最近更新 更多