1

我正在尝试在 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;
}
4

2 回答 2

2

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

waitpid(pid, &status, 0);

分叉出子进程的主进程等待子进程退出,然后继续循环,并开始下一个进程。

由于您想同时运行您的进程,您可以这样做:分配一个pid_tfor 进程 ID 数组,并将其填充到循环中。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]);
}
于 2013-10-26T01:47:25.177 回答
0

当然。您的父进程正在等待子进程在再次分叉之前完成执行。您只是按顺序运行 cmd N 次。

于 2013-10-26T01:47:37.347 回答