在C中运行N个并发进程

时间:2013-10-26 01:44:56

标签: c process fork

我正在尝试在C程序中运行N个并发进程。我已经构建了一个简单的示例,它将命令作为参数,为每个命令创建一个fork,然后执行它。

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

int main(int argc, char **argv)
{
  int i;
  for(i = 1; i < argc; i++)
  {
    pid_t pid = fork();
    if(pid < 0)
    {
      fprintf(stderr, "forking error\n");
      exit(1);
    }
    else if(pid > 0)
    {
      int status;
      waitpid(pid, &status, 0);
      printf("Command %s has completed successfully by PID=%d\n", argv[i], pid);
    }
    else
    {
      char cmd[1024];
      sprintf(cmd, "%s", argv[i], i);
      system(cmd);
      _exit(1);
    }
  }
  printf("Finished\n");
  return 0;
}

这似乎正确地运行了进程,但不能同时运行。关于我做错了什么的任何想法?

编辑:我根据建议进行了编辑,但这似乎也不起作用。

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

int main(int argc, char **argv)
{
  int i;
  pid_t *pids = malloc( sizeof(pid_t) * (argc) );
  int *statuses = malloc( sizeof(int) * (argc) );
  for(i = 1; i < argc; i++)
  {
    pid_t pid = fork();
    if(pid < 0)
    {
      fprintf(stderr, "forking error\n");
      exit(1);
    }
    else if(pid > 0)
    {
      //int status;
      //waitpid(pid, &status, 0);
      //printf("Command %s has completed successfully by PID=%d\n", argv[i], pid);
      pids[i] = pid;
    }
    else
    {
      char cmd[1024];
      sprintf(cmd, "%s > out.%d", argv[i], i);
      system(cmd);
      _exit(1);
    }
  }

  int needtowait = 0;
  do
  {
    needtowait = 0;
    for(i = 1; i < argc; i++)
    {
      if(pids[i] > 0)
      {
        if(waitpid(pids[i], &statuses[i], 0) != 0)
        {
          pids[i] = 0;
          char *successstr = "successfully";
          if(statuses[i])
          {
            successstr = "unsuccessfully";
          }
          printf("Command %s has completed %s by PID=%d\n", argv[i], successstr, pids[i]);
        }
      }
      else
      {
        needtowait = 1;
      }
      sleep(0);
    }
  } while(needtowait);


  printf("Finished!\n");
  return 0;
}

2 个答案:

答案 0 :(得分:2)

您没有同时运行这些进程的原因在于:

waitpid(pid, &status, 0);

分离子进程的主进程在继续循环之前等待子进程退出,并开始下一个进程。

由于您希望同时运行您的进程,您可以这样做:为进程ID分配pid_t数组,并在循环内填充它。一旦您离开循环,您可以通过循环执行waitpid调用来等待各个进程完成。

pid_t *pids = malloc(argc * sizeof(pid_t));
for (int i  = 0 ; i < argc ; i++) { // Start i at 0, not at 1
    pid_t pid = fork();
    if (pid < 0) {
        ...
    } else if (pid > 0) {
        pids[i] = pid;
    } else {
        char cmd[1024];
        sprintf(cmd, "%s", argv[i+1], i+1);
        system(cmd);
        _exit(1);
    }
}
for (int i  = 0 ; i < argc ; i++) {
    int status;
    waitpid(pids[i], &status, 0);
    printf("Command %s has completed successfully by PID=%d\n", argv[i+1], pids[i]);
}

答案 1 :(得分:0)

不确定。您的父进程正在等待子进程在再次分叉之前完成执行。你只是连续N次运行cmd。