【问题标题】:How to fork n children and have them execute different tasks in C?如何分叉 n 个孩子并让他们在 C 中执行不同的任务?
【发布时间】:2015-09-12 08:21:39
【问题描述】:

我正在尝试从一个父进程创建 4 个子进程,并让每个子进程执行不同的操作。

int main(void) {
int processes = 4;
int i;
for (i = 1; i <= processes; i++) {
    if (fork() == 0) {
        printf("pid: %d\n", getpid());
        exit(0);
    }
}
int status;
for (i = 1; i <= processes; i++)
    wait(&status);
}

现在输出产生 PID:5847 PID:5846 PID:5845 PID:5844

为什么 pid 的顺序是递减而不是递增?我没有正确使用 fork() 来创建孩子吗?

【问题讨论】:

  • pid 可以按任何顺序排列 - 为什么您不这么认为?

标签: concurrency fork


【解决方案1】:

这是一种视错觉。 PID 是按递增顺序排列的;)让我解释一下:

  • 首先,创建进程 5844
  • 然后创建进程 5845
  • 然后创建进程 5846
  • 然后创建进程 5847
  • 然后进程 5847 被操作系统调度程序选择并打印“5847”
  • 然后进程 5846 被操作系统调度程序选择并打印“5846”
  • 然后进程 5845 被操作系统调度程序选择并打印“5845”
  • 然后进程 5844 被操作系统调度程序选择并打印“5844”

您无法控制调度程序首先选择哪个进程。但是,如果您在 for 循环的末尾添加 sleep(1);,我确信 PID 将按递增顺序排列(除非您达到上限并且它们环绕。)

至少 Linux 和 OS X 以递增顺序生成 PID,不了解其他类 Unix 操作系统。


#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(void) {
    int processes = 4;
    int i;
    int fork_result;
    int number_of_children;
    for (i = 1; i <= processes; i++) {
        fork_result = fork();
        if (fork_result > 0) {
            printf("parent says: hello child #%d, how are you?\n", fork_result);
            number_of_children++;
        } else if (fork_result == 0) {
            printf("pid: %d\n", getpid());
            exit(0);
        } else if (fork_result < 0) {
            printf("parent says: fork() failed\n");
        }
    }
    int status;
    for (i = 1; i <= number_of_children; i++) {
        wait(&status);
    }
}

在我的系统 (OS X 10.10.5) 上打印:

parent says: hello child #2577, how are you?
parent says: hello child #2578, how are you?
pid: 2577
pid: 2578
parent says: hello child #2579, how are you?
parent says: hello child #2580, how are you?
pid: 2579
pid: 2580

您使用的是什么操作系统?在任何情况下,“父母说:”行都应该按递增顺序排列。

【讨论】:

  • 感谢您对正在发生的事情的精彩解释。这使它更加清晰。我正在使用 Ubuntu 并添加 sleep(1) 确实允许它以递增的顺序打印。你能用等待解释最终的 for 循环吗?不管它是否存在,它似乎都会计算总和。
  • @omgitsbd - 使用 wait(),父进程等待子进程完成。如果你省略它,父进程可能会比子进程更早退出:这会杀死剩余的子进程,你只会看到子进程的一部分输出,或者根本没有输出。但是,如果孩子比父母快,您将无法观察到差异。除了你必须注意不要产生太多的僵尸 => 但在示例中这不是问题,因为僵尸在父级退出时被垃圾收集。
猜你喜欢
  • 2015-05-29
  • 2015-05-02
  • 1970-01-01
  • 1970-01-01
  • 2020-08-20
  • 1970-01-01
  • 1970-01-01
  • 2019-11-20
  • 1970-01-01
相关资源
最近更新 更多