【问题标题】:Does calling main from main spawn a new process?从 main 调用 main 会产生一个新进程吗?
【发布时间】:2015-12-05 19:05:19
【问题描述】:

从 main 调用 main 会为被调用的 main 生成一个新进程,还是在同一个进程中调用 main?

我读到 main 返回的值是由执行它的进程返回的。

【问题讨论】:

  • 为什么会这样?你只是在调用一个标准函数,就像你调用 printf 一样。
  • C 不知道进程。这在像 DOS 这样的单进程操作系统上怎么可能?
  • @Olaf 有趣的是 DOS 确实 有进程的概念,虽然它们一次只运行一个......参见例如Int 21/AH=26h.
  • @FelixPalmen:“单进程操作系统”不就是这个意思吗? CLI 将如何启动另一个程序? (我没有编程DOS,但TOS很相似)。
  • @Olaf,我指的是“这怎么可能……”部分——如果 C 想了解进程,即使在 DOS 上也是可能的。了解流程并不一定意味着多任务处理。

标签: c main


【解决方案1】:

它不会创建新进程。它只是在同一个进程中调用一个函数。

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

int start=1;

int main()
{
    if (start) {
        printf("in first call to main, pid=%d\n",getpid());
        start=0;
        return main();
    } else {
        printf("in second call to main, pid=%d\n",getpid());
        return 1;
    }
}

输出:

in first call to main, pid=15482
in second call to main, pid=15482

进程以状态 1 退出。

【讨论】:

    【解决方案2】:

    它不会创建另一个进程,但它会在自己内部嵌套 main()。会有一些奇怪的事情发生。如果您没有明确告诉 main 您已完全完成,它将继续运行并且该进程不会终止;因为对 main 的原始调用尚未完成。当你调用它时,它会嵌套在它自己内部。

    很好的问题。当我第一次学习 C 时,我有这个弹出窗口。我最后使用 main 来重新运行所有内容,而不仅仅是使用循环。我的老师说这不是一个好习惯。

    【讨论】:

      【解决方案3】:

      我读到 main 返回的值是由执行它的进程返回的。

      这是因为 C 运行时将调用 main() 并在其执行后执行一些特定于操作系统的操作以将退出状态设置为 main() 返回的任何内容。不过main()并没有什么特别之处,只是一个普通的功能。

      这特别意味着它不是您程序的入口点...真正的入口点由链接到您的程序的 C 运行时提供,并从那里调用 main()

      作为示例,请参阅我最近为 DOS .COM 可执行文件自己的运行时编写的一些代码:

      __asm__ (
              "   .section    .comstartup             \n"
              "   .globl      __com__start            \n"
      
              /* THIS is the real entry point, call a function to get some info
               * about the console and then jump to a function getting command
               * line arguments from DOS and calling main */
      
              "__com__start:                          \n"
              "   call        _getcinfo               \n"
              "   jmp         argstart                \n"
              "   .text                               \n");
      
      void __attribute__((__noreturn__)) exit(int status)
      {
          /* this just calls the DOS function for exiting with exit status */
          __asm__ volatile (
                  "mov    $0x4c, %%ah     \n\t"
                  "int    $0x21           \n\t"
                  :
                  : "a" (status)
                  );
          __builtin_unreachable();
      }
      
      static void argstart(void)
      {
          char *cmdline = (char *)0x81;
          argc = 1;
          argv[0] = progname();
      
          {
              /* some code to populate argv[] */
              [....]
          }
      
          /* and this could be a quite typical line in any C runtime, just
           * call exit() with whatever main() returns: */
          exit(main(argc, argv));
      }
      

      【讨论】:

        【解决方案4】:

        main函数在同一个进程中被调用,可以通过打印getpid()返回的值来检查,如下:

        int main(){
           static int i = 2;
           if (i>0){
              int pid1 = getpid();
              printf("Main: %d\n", pid1);
              i--;
              main();
           }
        
        }
        

        输出是

        Main: 32323
        Main: 32323
        

        这确认 main 是在与系统调用第一个进程相同的进程中调用的。

        【讨论】:

        • if() 之外执行int pid1 = getpid(); printf("Main: %d\n", pid1); 将是更有力的证据。据我们所知,main() 第三次被调用(系统第一次,代码两次),它有一个不同的 pid。
        猜你喜欢
        • 2012-09-22
        • 1970-01-01
        • 1970-01-01
        • 2022-12-31
        • 1970-01-01
        • 2011-10-07
        • 2011-04-03
        • 2016-07-14
        • 2017-09-27
        相关资源
        最近更新 更多