【问题标题】:Fork Arbitrary Amount of Children from a Parent in C?在 C 中从父母那里分叉任意数量的孩子?
【发布时间】:2009-09-22 22:10:00
【问题描述】:

我已经找到了如何通过这样的方式分叉多个孩子的示例:

if ( fork() = 0 ) {
    //In child
} else {
    if ( fork() = 0 ) {
       //in second child

但如果我不知道自己需要多少个孩子,我该怎么做呢?

例如,如果我有一个命令的链接列表,并且我想为每个命令分叉和执行...所以我想我也需要知道它是哪个子...

【问题讨论】:

  • 那么,你在做本科的shell作业吗?
  • BobbyShaftoe:我猜,只是为了我自己,我是一名音乐专业的 ;-)

标签: c fork


【解决方案1】:

相信您需要为链表执行此操作:

linked_list_of_commands_t *node = root;
while (node != NULL) {
   int pid = fork();
   if (pid == -1) {
       break; // handle error
   } else if (pid == 0) {
       // child
       execv(node->command, node->argv);
       exit(1); // execv should not return, but just in case the execv call fails
   } else {
       node = node->next;
   }
}

这将为列表中的每个项目启动一个单独的进程。

【讨论】:

  • 这是一个很好的答案。值得注意的是,在 POSIX 系统上,errno 是在 exec* 函数之一失败后设置的。
  • @BobbyShaftoe:是的,你可以报告错误——但仅仅 exec-family 函数返回就意味着它失败了。
【解决方案2】:

但例程的数量必须固定,即使在这些分支上的执行是无限的。那么对于每个例程都有某种 switch 语句逻辑的 while 循环呢?

【讨论】:

  • 我发布了一个包含骨架代码的答案(带有 for 循环而不是 while)
  • 其他帖子有很好的例子。但是当我说“切换”时,我指的是似乎是多个执行选项。他们展示的一个简单循环可以多次运行一个编码例程(分叉),但您似乎需要多个例程(第一个和第二个等)。开关(但不一定是关键字)部分用于运行哪个例程(第一个或第二个等)的某些决策标准。您不知道要运行多少,但例程的 /options/ 不可能是无限的,对吧?
  • 杰森,没错,这不会总是一样的例行公事......我想这就是我被绊倒的地方......
  • Kyle,你在做什么来确定应该选择所有可用例程中的哪个例程?
  • 而且,这并不重要,但确实想要一长串后代或基本上是一个有很多孩子的父母?
【解决方案3】:

怎么样

for (i=0; i< 1000; i++) {
    pid = fork();
    if (pid) {
        // Error handling for pid==-1 
        break;
    }
    // Some logic dependent on value of 'i'
}

【讨论】:

  • 所以每个孩子我都会不一样?
  • 正确 - 第一个孩子将在 i==0 时分叉,第二个将在 i==1 时分叉,等等...所以如果您的命令位于“char*”数组中,您可以简单地将命令执行为“command_array[i]”
【解决方案4】:
for(i = 0; i < num_children_to_spawn(); ++i) {
    pid_t pid = fork();
    if (pid == -1) {
        exit(-1); /* error */
    } else if (pid == 0) {
        /* child */
        do_child_things();
        break;
    } else {
        /* parent */
    }
}

请注意,我没有使用 switch(),因为它会使 break 退出循环变得更加麻烦。

【讨论】:

  • break?你一般不想在子代码块的末尾exit()吗?
【解决方案5】:
pid_t children_pids[MAX_CHILDREN];
int last_child_index = 0;
for (int i=0; i < num_wanted_children; i++) {
  pid_t pid = fork();
  if (pid == 0)
    // in child
  else
    children_pids[last_child_index++] = pid;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-05-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-22
    • 1970-01-01
    相关资源
    最近更新 更多