使用fork()以广度优先顺序打印序列

时间:2014-09-05 12:38:39

标签: c fork

给定一个流程树

             A
           /   \
          /     \
         B       C
        / \     / \
       D   E   F   G

我被要求以BFS顺序打印序列,即使用fork()系统调用ABCDEFG,其中每个节点表示一个具有相同父子构造的进程,如树所示(即A是B和C的父, B是D和E的父母,就像那样)。

我想出了这个解决方案,但我真的不明白如何以递归方式进行打印。

static int count;
char *msg[] = {"A", "B", "C", "D", "E", "F", "G"};
main(){
  if(!fork()){ //Child 1
    printf("%s\t\t%d\t\t%d\n", msg[count++], (int)getpid(), (int)getppid());
  }
  else{
    if(!fork()){ //Child 2
        printf("%s\t\t%d\t\t%d\n", msg[count++], (int)getpid(), (int)getppid());
    }
  } 
}

此逻辑仅打印A-B-C,如何使其递归以便打印到G? 请帮忙。感谢。

1 个答案:

答案 0 :(得分:1)

以下代码执行您所需的操作但不保证将首先打印哪个叶子(相同级别的打印顺序)。

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
#include <linux/wait.h>

typedef struct node {
  char data;
  struct node *left;
  struct node *right;
} node;

void pretty_print(node *nodes[], int size)
{
  int fork_cnt = 0;

  for (int i=0; i < size; i++) {
    if (fork() == 0) {
      // Child path.
      printf("%c (pid: %d, parent: %d)\n", nodes[i]->data, (int)getpid(), (int)getppid());
      node *children_nodes[256];
      int children_sizes = 0;
      if (nodes[i]->left)
    children_nodes[children_sizes++] = nodes[i]->left;
      if (nodes[i]->right)
    children_nodes[children_sizes++] = nodes[i]->right;
      if (children_sizes) {
    if (fork() == 0) {
      pretty_print(children_nodes, children_sizes);
      return;
    }
      }
      return;
    } else {
      // Parent path.
      fork_cnt++;
    }
  }

  for (int i=0; i < fork_cnt; i++) {
    // wait all children.
    int status;
    wait(&status);
  }
}

int main(void) 
{
  node g = {'G', NULL, NULL};
  node f = {'F', NULL, NULL};
  node e = {'E', NULL, NULL};
  node d = {'D', NULL, NULL};
  node b = {'B', &d, &e};
  node c = {'C', &f, &g};
  node a = {'A', &b, &c};

  node *root[1] = {&a};
  pretty_print(root, 1);
  return 0;
}