在C中分叉 - 无限循环?

Uba*_*ade 4 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;
}
Run Code Online (Sandbox Code Playgroud)

#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;
}
Run Code Online (Sandbox Code Playgroud)

Joh*_*all 5

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

if (pid == 0) {
    ....
}
Run Code Online (Sandbox Code Playgroud)

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

if (pid != 0) {
    ....
}
Run Code Online (Sandbox Code Playgroud)

此外,您永远不会检查pid == -1(fork()失败).

写这样的更标准的方法是:

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 */
Run Code Online (Sandbox Code Playgroud)