在C中分叉 - 无限循环?

时间:2016-01-05 01:29:38

标签: c fork

尝试学习C分叉。它正确打印主循环运行的次数和正确的线程数,但执行时间关闭,程序永远不会终止。我是否制作了无数的流程?

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

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

更新**:我找到了解决方案。我认为第一个问题是我没有等待命令,第二个问题是在等待时我意外地删除了计数检查<的argv [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. 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;
}

1 个答案:

答案 0 :(得分:5)

最大的问题是你孩子的代码:

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

属于父代码的同一个循环(就在右边):

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 */