简体   繁体   English

派生多个子进程以运行其他程序

[英]fork multiple child processes to run other programs

I want from parent program (called daemon) to start 5 child processes of test program with args(all 5 in parallel, not to wait to finish). 我想从父程序(称为守护程序)开始使用args(全部5个并行,而不是等到完成)启动5个测试程序的子进程。

I have the following code: 我有以下代码:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(int argc,char* argv[]){

    //missing irrelevant part where argum is set

    int status,i;
    char cmd[512];
    pid_t process_id = 0;
    for (i=0; i<=5;i++)
    {
        process_id = fork();
        if (process_id < 0)
        {
            printf("fork failed - %d!\n",i);
            continue;
        }
        else if(process_id > 0) {
            printf("process_id of child process %d \n", process_id);
        }
        else
        {
            sprintf(cmd,"./test %s",argum);
            status = system(cmd);
            exit(0);
        }
    }
    return 0;
}

it starts them but when I run ps -aux to see the processes, besides the good ones (like: ./test [args]) there are some duplicates like: sh -c ./test [args] 它启动了它们,但是当我运行ps -aux来查看进程时,除了好的进程(例如:./test [args])之外,还有一些重复项,例如:sh -c ./test [args]

How can I get rid of those starting with "sh -c" ? 我如何摆脱以“ sh -c”开头的内容?

Instead of calling system() from the child, use a member of the exec*() family of functions. 而不是从子级调用system() ,请使用exec*()函数家族的成员。

Calling execXYZ() from the fork() ed off child process replaces the child process by the new process created from what had been passed to the execXYZ() call. 从已退出子进程的fork()调用execXYZ()将子进程替换为根据已传递给execXYZ()调用的内容创建的新进程。

Please note that if execXYZ() succeeds it does not return. 请注意,如果execXYZ()成功执行,则不会返回。


Example for executing /bin/ls -alrt *.c : 执行/bin/ls -alrt *.c示例:

  • The execl*() members of the family expect each white-space separate command line option as a single parameter. 该家族的execl*()成员希望将每个空格分隔的命令行选项作为单个参数。

     execl("/bin/ls", "ls", "-alrt", "*.c", (char*) 0); execlp("ls", "ls", "-alrt", "*.c", (char*) 0); 
  • The execv*() members of the family expect each white-space separate command line option in the way parameters are passed to main() : 该家族的execv*()成员期望将参数传递给main()的方式中的每个空格分隔的命令行选项:

     char * const argv[] = { "ls", "-alrt", "*.c", NULL, } execv("/bin/ls", argv); execvp("ls", argv); 

The exec*p() family members make use of the environment's variable PATH to search for the binary to be executed. exec*p()系列成员利用环境的变量PATH搜索要执行的二进制文件。 So for this example (as for the system command ls ) the path does need to be specified. 因此,对于此示例(对于系统命令ls ),确实需要指定路径。


At test program: 在测试程序中:

#include <unistd.h>  
#include <stdio.h>

/* This should list the current working directory. */

int main(void)
{
  execl("/bin/ls", "ls", "-al", "-rt", (char*) 0);
  perror("execl() failed");
  return 0;  
}

The simplest way to lose sight of the sh -c entries is: 忽略sh -c条目的最简单方法是:

sprintf(cmd, "exec ./test %s", argum);

The exec replaces the shell run by system() with the command, instead of having the shell hang around until the ./test process terminates. exec用命令替换由system()运行的shell,而不是让shell一直挂着直到./test进程终止。

The alternative is outlined by alk in his answer — use the exec*() family of functions (system calls). alk在他的答案中概述了替代方法-使用exec*()系列函数(系统调用)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM