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

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

这真的取决于你正在尝试做什么,确切地说,因为它是:

  1. OS依赖
  2. 不太清楚你想要做什么。

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

 #include  #include  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。

希望这有帮助。

如果你想执行更复杂的操作,比如读取外部程序的输出, popen系统调用可能会更好。 例如,要以编程方式访问目录列表(这是一个有点愚蠢的示例,但作为示例有用),您可以编写如下内容:

 #include  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 ... 
 #include  int main() { system("echo HAI"); return 0; } 

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

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

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

这是一个解释Fork,System,Exec之间所有细微差别的页面。

如果您在Win,Mac和Linux上工作,我可以向您推荐Qt Framework及其QProcess对象 ,但我不知道这是否适合您。 最大的好处是你可以在windows linux和mac上编译相同的代码:

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

而对于额外的,您甚至可以从母进程中杀死子进程,并通过流与其保持通信。

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

 int system(const char *string); 

系统api的例子

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

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