1

我希望从父程序(称为守护程序)使用 args 启动 5 个测试程序的子进程(全部 5 个并行,而不是等待完成)。

我有以下代码:

#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;
}

它会启动它们,但是当我运行 ps -aux 来查看进程时,除了好的进程(例如:./test [args])之外,还有一些重复项,例如:sh -c ./test [args]

我怎样才能摆脱那些以 "sh -c" 开头的?

4

2 回答 2

2

system()不要从孩子那里调用,而是使用exec*()函数家族的成员。

execXYZ()从ed off 子进程调用fork()会将子进程替换为从传递给execXYZ()调用的内容创建的新进程。

请注意,如果execXYZ()成功,它不会返回。


执行示例/bin/ls -alrt *.c

  • execl*()系列的成员希望将每个空格分隔的命令行选项作为单个参数。

    execl("/bin/ls", "ls", "-alrt", "*.c", (char*) 0);
    execlp("ls", "ls", "-alrt", "*.c", (char*) 0);
    
  • execv*()系列的成员希望将参数传递给每个空格单独的命令行选项main()

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

exec*p()家族成员使用环境变量来PATH搜索要执行的二进制文件。因此,对于这个示例(对于系统命令ls),确实需要指定路径。


在测试程序中:

#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;  
}
于 2013-09-09T13:40:06.523 回答
1

忽略sh -c条目的最简单方法是:

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

用命令exec替换运行的 shell ,而不是让 shell 在进程终止system()之前一直挂起。./test

alk在他的回答中概述了替代方案——使用exec*()函数族(系统调用)。

于 2013-09-09T15:06:08.573 回答