如何将参数传递给由fork()创建的进程

18

我希望使用C语言中的fork()函数创建进程的副本,但是我无法弄清如何向这些副本传递参数。例如,我想要向副本进程传递一个整数。

另外,如果我在一个循环中调用fork(),并且想向每个进程传递唯一的值(例如0...N),该怎么办?

for (int i = 0; i < 4; ++i) {
    fork();
    // pass a unique value to new processes.
}

2
fork 创建一个正在进行的进程的副本,它不会初始化一个进程。 - Beta
阅读 http://advancedlinuxprogramming.com/ - Basile Starynkevitch
5个回答

23

fork() 的好处是,每个您创建的子进程都会自动获得父进程的所有内容的副本。例如,假设我们想将一个 int 类型的变量 myvar 传递给两个子进程,但我希望每个子进程都有一个不同于父进程的值:

int main()
{
    int myvar = 0;
    if(fork())
        myvar = 1;
    else if(fork())
        myvar = 2;
    else
        myvar = 3;

    printf("I'm %d: myvar is %d\n", getpid(), myvar);
    return 0;
}

这样做可以使每个进程都拥有一个带有自己值的 myvar 的“副本”。

I'm 8517: myvar is 1
I'm 8518: myvar is 2
I'm 8521: myvar is 3

如果您没有更改该值,那么每个 fork 的进程将具有相同的值。


7

本地和全局变量在 fork() 过程中会自动保留,因此不需要“传递参数”。如果您在 forked 进程中调用函数,则可以执行以下操作:

pid_t pid = fork();
if (pid == 0) {
    funcToCallInChild(argument);
    exit(0);
}

6

我回复晚了,但是这是我的做法:

const char *progname = "./yourProgName";
const char *argument1 = "arg1";
const char *argument2 = "arg2";

if (fork() == 0)
{
    // We are the child process, so replace the process with a new executable.  
    execl(progname, progname, argument1, argument2, (char *)NULL);
}
//  The parent process continues from here.

首先,使用fork()方法创建一个新进程,它与旧进程共享同一内存空间。 fork()同时返回父进程和子进程。如果fork()返回值为零,则代表你是子进程。子进程接着使用execl()方法,用新文件的进程内存替换原来的进程内存。

请注意,在execl()方法中,progname被重复给定了两次,第一个参数实际上是execl()要运行的内容,第二个参数则是argv[0]。 你必须同时提供这两个参数,否则参数数量会少一个。Progname必须包含所有所需的路径信息以找到所需的可执行映像。

在这个例子中,我传递了两个参数,但你可以传递任意多个。 参数列表必须以NULL结尾,并且像我展示的那样需要将其转换为(char *)。

这种方法提供了一个完全独立的进程,具有参数和唯一的pid。 它可以在父进程终止后继续运行,也可能在父进程之前终止。


1

请查看exec()函数族

编辑:如果您正在尝试初始化与基本进程相同的程序副本,请继续使用duskwuff建议的变量。


1

3
不,请不要这样做。clone 是一个复杂的、仅适用于 Linux 的系统调用,需要对 Linux 有很好的了解,并且通常只保留给少数实现线程库(例如 pthread)的专家。请参阅 futex(7) 手册页。 - Basile Starynkevitch
@BasileStarynkevitch: 没错。只有在进行一些真正的低级别黑客技术时才使用clone--clone的唯一目的是允许您在用户空间执行以前只能在内核空间执行的一些操作,例如线程实现。它不是通用的系统调用。 - Linuxios

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接