代码之家  ›  专栏  ›  技术社区  ›  andrewrk

如何在C中生成另一个进程?

  •  26
  • andrewrk  · 技术社区  · 16 年前

    8 回复  |  直到 8 年前
        1
  •  21
  •   FreeMemory    16 年前

    这完全取决于你想做什么,确切地说,它是:

    1. 依赖于操作系统
    2. 不太清楚你想做什么。

    不过,我会尽量提供一些信息供你决定。
    在UNIX上, fork() 从调用fork的位置创建进程的克隆。意思是,如果我有以下过程:

    #include <unistd.h>
    #include <stdio.h>
    
    int main()
    {
        printf( "hi 2 u\n" );
        int mypid = fork();
    
        if( 0 == mypid )
            printf( "lol child\n" );
        else
            printf( "lol parent\n" );
    
        return( 0 );
    }
    

    你好2 u

    lol家长

    当你 叉子() 在子级中返回的pid是0,在父级中返回的pid是子级的pid。请注意,“hi2u”只打印一次。。。由 起源 .

    execve() 它的函数族几乎总是与 fork(). 执行() 类似的操作会用传递给它的应用程序的名称覆盖当前的stackframe。 执行() 几乎总是与 叉子() 在那里你分叉一个子进程,如果你是父进程,你做你需要继续做的任何事情,如果你是子进程,你执行一个新进程。 也几乎总是与 waitpid() --waitpid获取一个子进程的pid,非常确切地说, 等待

    使用这些信息,您应该能够编写一个非常基本的shell;在命令行上使用进程名并运行您告诉它的进程。当然,shell做的不止这些,比如管道输入和输出,但是您应该能够使用 叉子() , 执行() waitpid() .

    注意:这是*nix特有的!这在Windows上不起作用。

    希望这有帮助。

        2
  •  16
  •   Blair Conrad    16 年前

    如果您想执行更复杂的操作,例如读取外部程序的输出,则 popen 系统调用。例如,以编程方式访问目录列表(这是一个有点傻的示例,但很有用 例如),您可以这样写:

    #include <stdio.h>
    
    int main()
    {
      int entry = 1;
      char line[200];
      FILE* output = popen("/usr/bin/ls -1 /usr/man", "r");
      while ( fgets(line, 199, output) )
      {
        printf("%5d: %s", entry++, line);
      }
    }
    

    像这样输出

    1: cat1
    2: cat1b
    3: cat1c
    4: cat1f
    5: cat1m
    6: cat1s
    ...
    
        3
  •  11
  •   andrewrk    9 年前
    #include <stdlib.h>
    
    int main()
    {
        system("echo HAI");
    
        return 0;
    }
    
        4
  •  8
  •   Lothar    12 年前

    我想给你一个很大的警告,不要使用系统和100%永远不要使用系统,当你写一个库。它是30年前设计的,当时多线程还不为Unix这个玩具操作系统所知。即使现在几乎所有的程序都是多线程的,它仍然不可用。

    使用popen或做一个fork+execvp,所有其他的一切都会给你在信号处理、环境处理代码中的死机等方面难以发现的问题。这是纯粹的邪恶和耻辱的选择和最有评价的答案是促进使用“系统”。在工作场所推广使用可可碱更健康。

        5
  •  3
  •   feedc0de RushPL    8 年前

    在UNIX上,我认为如果您希望派生的进程独立于spawing进程运行,那么基本上需要分叉它:例如,如果您不希望在退出派生进程时终止派生进程。

    Here is a 解释Fork、System、Exec之间所有细微差别的页面。

    如果你在Win、Mac和linux上工作,我可以向你推荐 Qt Framework and its QProcess object ,但我不知道这是否是你的选择。最大的优点是您可以在windows linux和mac上编译相同的代码:

     QString program = "./yourspawnedprogram";
     QProcess * spawnedProcess = new QProcess(parent);
     spawnedProcess->start(program);
     // or spawnedProcess->startDetached(program);
    

    另外,你甚至可以从母亲过程中消灭孩子进程, 通过一条小溪和它保持联系。

        6
  •  2
  •   gradbot    16 年前

    一种解决方案是stdlib.h中定义的系统函数

    int system(const char *string);
    

    system api example

        7
  •  1
  •   mouviciel    16 年前

    如果需要检查/读取/解析外部命令的输出,我建议使用popen()而不是system()。

        8
  •  1
  •   Constantin    16 年前

    说到平台依赖的菜谱,在Windows上使用 CreateProcess ,在Posix(Linux、Mac)上使用 fork execvp . 但是 system() 应该满足您的基本需求,是标准库的一部分。