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

时间:2008-08-19 22:53:47

标签: c process

如何运行外部程序并使用C传递命令行参数?如果必须使用操作系统API,请包含适用于Windows,Mac和Linux的解决方案。

8 个答案:

答案 0 :(得分:16)

这实际上取决于你正在尝试做什么,确切地说,它是:

  1. 依赖于操作系统
  2. 不太清楚你要做什么。
  3. 尽管如此,我会尝试提供一些信息供你决定 在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
        大声笑的孩子
        哈哈父母

      

    当你fork()在孩子中返回的pid是0,而在父母中返回的pid是孩子的pid。请注意,“hi2u”仅由父级打印一次。

    execve()及其函数族几乎总是与fork(). execve()一起使用,等等会使用您传递给它的应用程序的名称覆盖当前的堆栈帧。 execve()几乎总是与fork()一起使用,您可以在其中分叉子进程,如果您是父进程,则执行您需要继续执行的操作,如果您是孩子,则执行新进程。 execve()也几乎总是与waitpid()一起使用 - waitpid需要一个子进程的pid,而且确实,等待,直到子进程终止并将子进程的退出状态返回给您。

    使用此信息,您应该能够编写一个非常基本的shell;一个在命令行上获取进程名称并运行您告诉它的进程。当然,shell不仅仅是管道输入和输出,但你应该能够使用fork()execve()waitpid()来完成基础知识。

    注意:这是* nix特定的!这不适用于Windows。

    希望这会有所帮助。

答案 1 :(得分:15)

如果您想执行更复杂的操作,例如阅读外部程序的输出,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
...

答案 2 :(得分:12)

#include <stdlib.h>

int main()
{
    system("echo HAI");

    return 0;
}

答案 3 :(得分:5)

我想对不使用系统发出重大警告,并且在编写库时100%从不使用系统。它是在30年前设计的,当时称为Unix的玩具操作系统不知道多线程。即使今天几乎所有程序都是多线程的,它仍然无法使用。

使用popen或做一个fork + execvp,其他一切都会让你很难找到信号处理,环境处理代码崩溃等问题。这是纯粹的邪恶和耻辱,所选和最受好评的答案正在促进使用“系统”。在工作场所推广使用Cocain更健康。

答案 4 :(得分:4)

在UNIX上,我认为你基本上需要分叉它,如果你想让衍生的进程从你的进程中分离出来:例如,如果你不希望在你退出产生进程时你的生成进程终止。

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);

另外,你甚至可以从母进程中杀死子进程, 并通过流保持与它的沟通。

答案 5 :(得分:2)

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

int system(const char *string);

system api example

答案 6 :(得分:1)

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

答案 7 :(得分:1)

说到平台相关的配方,在Windows上使用CreateProcess,在Posix(Linux,Mac)上使用fork + execvp。但system()应该涵盖您的基本需求,并且是标准库的一部分。