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

and*_*wrk 27 c process

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

Fre*_*ory 18

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

  1. OS依赖
  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 );
}
Run Code Online (Sandbox Code Playgroud)

输出结果如下:

嗨2你好
lol孩子
哈哈父母

当你fork()在孩子中返回的pid为0时,父亲返回的pid是孩子的pid.请注意,"hi2u"仅由父母打印一次.

execve()并且它的函数族几乎总是用来等用fork(). execve()您传递给它的应用程序的名称覆盖当前的堆栈帧.execve()几乎总是与fork()你分叉子进程的地方一起使用,如果你是父进程,你做任何你需要继续做的事情,如果你是孩子你执行一个新的进程.execve()也几乎总是使用waitpid()- waitpid接受一个子进程的pid,并且确切地说,等待直到子进程终止并将子进程的退出状态返回给你.

使用这些信息,您应该能够编写一个非常基本的shell; 一个在命令行上获取进程名称并运行您告诉它的进程.当然,贝壳做更多的事,像管道输入和输出,但你应该能够完成使用的基本知识fork(),execve()waitpid().

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

希望这有帮助.


Bla*_*rad 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);
  }
}
Run Code Online (Sandbox Code Playgroud)

给出这样的输出

1: cat1
2: cat1b
3: cat1c
4: cat1f
5: cat1m
6: cat1s
...
Run Code Online (Sandbox Code Playgroud)


wil*_*ell 11

#include <stdlib.h>

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

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

  • 切勿使用系统.远离多线程安全,它会在你的垃圾中狠狠地咬你.例如,信号处理错误是一些最令人讨厌的问题,"系统"充满了它. (6认同)

Lot*_*har 6

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

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


ful*_*ton 5

在 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);
Run Code Online (Sandbox Code Playgroud)

此外,您甚至可以从母进程中终止子进程,并通过流与其保持通信。