在 C 中分叉 - 无限循环?

Forking within C - infinite loop?

正在尝试学习 C 分支。它正确地打印出主循环假设 运行 的次数和正确的线程数,但执行时间已关闭并且程序永远不会终止。我是否正在制作无限数量的流程?

经过一些建议,这里是一个更清晰的代码版本。旧版本位于下方。更新的部分仍在创建许多子进程并且永远不会退出。我只是看不出出了什么问题。

更新:John Hascall 的建议修复了格式和线程 运行ning 乱序。仍然会生成无限数量的线程,但现在顺序正确。即打印线程执行时间 1、2、3、4...等。不要认为问题是 wait 系统调用,而是去研究它,看看我是否找不到任何东西。

更新**:我找到了解决方案。我认为第一个问题是我没有等待命令,第二个是在等待时我不小心删除了对 count < argv[1] 的检查。我把它放回去,它似乎 运行ning 正确!感谢大家的帮助和风格指导!工作版本如下。

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "./processes.h"

int main(int argc, char** argv) {
  if (argc != 4) {
    printf("Wrong number of arguments entered. Usage: #processes sleepTime inputFile.\n");
    return 1;
  }

  if(atoi(argv[1]) <= 0){
    printf("Incorrect number of children, must be greater than 0");
    return -1;
  }

  int count = 0;
  int index;
  Child *child = malloc(sizeof(Child) * atoi(argv[1]));
  int childIndex;
  int pid;

  do{
    switch (pid = fork()){
      case -1:
        printf("Fork failed\n");
        exit(1);

      case 0:
        sleep(atoi(argv[2]) * childIndex);
        gettimeofday(&child[childIndex].endTime, NULL);
        double elapsed = child[childIndex].endTime.tv_usec - child[childIndex].startTime.tv_usec;
        printf("Time for process %d = %f microseconds\n", childIndex, elapsed);
        break;

     default: 
        childIndex = count + 1;
        gettimeofday(&child[count].startTime, NULL);
        child[count].index = count + 1;
        child[count].pid = pid;
        count++;
    }
  } while((wait(NULL) != -1) && (count < atoi(argv[1])));

  return 1;
}

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "./processes.h"

int main(int argc, char** argv) {
  if (argc != 4) {
    printf("Wrong number of arguments entered. Try again.");
    return 1;
  }

  if(atoi(argv[1]) <= 0){
    printf("Incorrect number of children, must be greater than 0");
    return -1;
  }

  int count;
  int index;
  Child *child = malloc(sizeof(Child) * atoi(argv[1]));
  int pid = 1;
  int childIndex;

  for (count = 0; count < atoi(argv[1]); count++) {
    if (pid != 0) {
      childIndex = count + 1;
      gettimeofday(&child[count].startTime, NULL);
      child[count].index = count + 1;
      pid = fork();

      if (pid != 0){
        child[count].pid = pid;
        printf("Main thread loop: %d\n", count);
        printf("Child process: %d\n", getpid());
      } 
    }
  }

  if (pid == 0) {
    //this is the child process
    sleep(atoi(argv[2]) * childIndex);
    gettimeofday(&child[childIndex].endTime, NULL);
    double elapsed = child[childIndex].endTime.tv_usec - child[childIndex].startTime.tv_usec;
    printf("Time for process %d = %f microseconds\n", childIndex, elapsed);

    //printf("This is thread %d reporting in.\n", childIndex);
  }

//  printf("Testing\n");
return 1;
}

最大的问题是您的 child 代码:

if (pid == 0) {
    ....
}

属于 parent 代码的同一个循环(紧接着说):

if (pid != 0) {
    ....
}

此外,您从不检查 pid == -1fork() 失败)。

更标准的写法是:

switch (pid = fork()) {
    case -1:
         /* handle fork error */
         exit(1);
    case 0:
         /* child code goes here */
         _exit(0);
    default:
         /* parent code goes here */
}
/* Also you probably want to look into the `wait()` syscall. */
do {} while (wait(NULL) != -1);       /* <--- the very minimum */