C 进程 fork()

发布于 2024-10-17 10:08:27 字数 1354 浏览 2 评论 0原文

我正在探索父进程& UNIX 中的子进程概念。我写了这段小代码,认为 x 不。或者会创建流程。但它创建了一个不同的数字 -

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

int main(int argv, char *argc[])
{
    int i;
    pid_t childpid;

    for(i=0; i<3; i++)
    {
        childpid = fork();
        if(childpid == -1)
        {
            perror("Failed to Fork");
            return 1;
        }

        if(childpid == 0)
            printf("You are in Child: %ld\n", (long)getpid());
        else
            printf("You are in Parent: %ld\n", (long)getpid());
    }
    return 0;
}

OUTPUT:
You are in Parent: 30410
You are in Child: 30411
You are in Parent: 30410
You are in Child: 30412
You are in Parent: 30411
You are in Parent: 30410
You are in Child: 30413
You are in Child: 30414
You are in Parent: 30412
You are in Parent: 30411
You are in Child: 30415
You are in Child: 30416
You are in Parent: 30413
You are in Child: 30417

我知道在 fork() 情况下,父级或子级可能会在执行中获得优先权。这并不困扰我,困扰我的是正在执行的进程数量。为什么是14?而不是执行 fork() 时会发生的某个 2^n 数字;叉(); fork() 即 fork 一个接着一个。

我缺少什么?

更新:还有一项澄清 -

fork 函数复制父级 内存映像以便新进程 接收地址空间的副本 父母的。

这意味着什么?这是否意味着

  1. 子进程在 fork() 语句之后开始执行?
  2. 子进程获取父进程变量的副本?那么如果x=3高于fork,子进程会看到这个x为3吗?

I am exploring parent process & child processes concept in UNIX. I wrote this small code thinking that x no. or processes would get created. But it has created a different number -

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

int main(int argv, char *argc[])
{
    int i;
    pid_t childpid;

    for(i=0; i<3; i++)
    {
        childpid = fork();
        if(childpid == -1)
        {
            perror("Failed to Fork");
            return 1;
        }

        if(childpid == 0)
            printf("You are in Child: %ld\n", (long)getpid());
        else
            printf("You are in Parent: %ld\n", (long)getpid());
    }
    return 0;
}

OUTPUT:
You are in Parent: 30410
You are in Child: 30411
You are in Parent: 30410
You are in Child: 30412
You are in Parent: 30411
You are in Parent: 30410
You are in Child: 30413
You are in Child: 30414
You are in Parent: 30412
You are in Parent: 30411
You are in Child: 30415
You are in Child: 30416
You are in Parent: 30413
You are in Child: 30417

I understand that in a fork() situation a parent or a child might get preference in execution. That's is not bothering me, what's bothering me is the number of processes that are getting executed. Why is it 14? and not some 2^n number which is what would happen if we are executing fork(); fork(); fork() i.e. fork's one after the other.

What am I missing?

UPDATE: One more clarification -

The fork function copies the parent
memory image so that the new process
receives a copy of the address space
of the parent.

What does this mean? Does it mean -

  1. the child process starts executing after the fork() statement?
  2. the child process gets a copy of the parent process variables? so if x=3 above fork, will the child process see this x as 3?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

仲春光 2024-10-24 10:08:27

您有 8 个进程正在执行,只是其中一些进程由于循环而多次打印。

如果对输出进行排序:

You are in Parent: 30410
You are in Parent: 30410
You are in Parent: 30410

You are in Parent: 30411
You are in Parent: 30411
You are in Child: 30411

You are in Parent: 30412
You are in Child: 30412

You are in Parent: 30413
You are in Child: 30413

You are in Child: 30414

You are in Child: 30415

You are in Child: 30416

You are in Child: 30417

那么您可以看到只有 8 个唯一的进程 ID。

其原因很微妙。因为子进程(几乎)继承了父进程的所有内容,所以它也获取循环的当前状态。我说“几乎”是因为某些东西是不同的,例如 PID(显然)、父 PID(同样明显)和某些资源限制(取决于操作系统)。

因此,当i == 0分叉成两个时,处理0。两者的下一个周期都在 i == 1 处。这两个都将在 i == 2 处分叉下一个周期。等等。

如果您检查下图,您可以看到创建过程。

      ____A____
     /    |    \
    B_    C_    D
    | \     \
    E  F     G
     \
      H

/|\ 行表示 i0 处的分叉>、12 分别。

请注意,从 i == 1 的父进程创建的进程(例如 E)只会使用 i == 2 进行分叉。换句话说,它是用 | 创建的,因此下一步是 \

类似地,使用 / (i == 0) 创建的 B 将仅使用 | (<代码>i == 1)和\i == 2)。

如果您对 fork 的其他信息感兴趣,请参阅我的长篇文章此处,以及有关 Linux 下不同 fork 选项内部结构的一些详细信息 这里

You have 8 processes there being executed, it's just that some of them are printing more than once because of the loop.

If you sort the output:

You are in Parent: 30410
You are in Parent: 30410
You are in Parent: 30410

You are in Parent: 30411
You are in Parent: 30411
You are in Child: 30411

You are in Parent: 30412
You are in Child: 30412

You are in Parent: 30413
You are in Child: 30413

You are in Child: 30414

You are in Child: 30415

You are in Child: 30416

You are in Child: 30417

then you can see that there are only 8 unique process IDs.

The reason for this is subtle. Because a child process inherits (almost) everything from the parent, it gets the current state of the loop as well. I say "almost" since certain things are different, such as the PID (obviously), parent PID (equally obviously) and certain resource limits (depending on the OS).

So, process 0 when i == 0 forks into two. both with their next cycle at i == 1. Both of these will fork with their next cycle at i == 2. And so on.

If you examine the following diagram, you can see the creation process.

      ____A____
     /    |    \
    B_    C_    D
    | \     \
    E  F     G
     \
      H

The lines /, | and \ represent forks at the points where i is 0, 1 and 2 respectively.

Note that a process (such as E) which was created from a parent where i == 1 will only fork with i == 2. In other words, it was created with | so its next step is \.

Similarly, B that was created with / (i == 0) will then only fork with | (i == 1) and \ (i == 2).

If you're interested in other information on fork, see my voluminous essay here, and some details on the internals of different fork options under Linux here.

如梦亦如幻 2024-10-24 10:08:27

当您调用 fork() 时,程序将在处理期间的位置准确启动。所以你有

i=0,2 个进程
i=1, 4 个进程
i=2, 8 个进程

,正如 rlibby 在他的评论中指出的那样,我忘记考虑以下事实:每一次原始通过都是总数的一部分。所以我的数学是错误的。应该是:

i=0,1个进程+1个新进程(总共2个)
i=1, 2 个进程 + 2 个新进程(总共 4 个)
i=2,4个进程+4个新进程(总共8个)

When you call fork(), the program starts EXACTLY where it was during processing. So you have

i=0, 2 processes
i=1, 4 processes
i=2, 8 processes

as rlibby pointed out in his comment, I forgot to take into account the fact that the processes from each of the original passes are part of the totals. So my math was wrong. It should be:

i=0, 1 process + 1 new (2 total)
i=1, 2 processes + 2 new (4 total)
i=2, 4 processes + 4 new (8 total)

梦毁影碎の 2024-10-24 10:08:27

我认为您看到创建如此多进程的原因是,当您fork子进程时,它位于for循环的中间。因此,在打印出它是一个子级之后,它将继续循环并分叉自己的子级。

要解决此问题,只需让子级在打印出它们是子级后退出即可:

if(childpid == 0) {
    printf("You are in Child: %ld\n", (long)getpid());
    exit(0);
}

顺便说一句,这确实解释了为什么您会看到一个循环有 2n 个进程进行 n 次迭代。在每次迭代中,每个进程都会分为两个进程,然后运行其余的循环迭代。这意味着每次迭代都会使进程数量加倍,因此在 n 次迭代之后,您将看到 2n 个进程。

希望这有帮助!

I think that the reason you're seeing so many processes get created is that when you fork a child process, it's in the middle of the for loop. Consequently, after it prints out that it's a child, it will then continue looping and forking its own children.

To fix this, just have the children exit after printing that they're children:

if(childpid == 0) {
    printf("You are in Child: %ld\n", (long)getpid());
    exit(0);
}

By the way, this does explain why you're seeing 2n processes for a loop doing n iterations. On each iteration, each process splits into two processes that then run for the rest of the loop iterations. This means that each iteration doubles the number of processes, so after n iterations you'll see 2n processes.

Hope this helps!

能怎样 2024-10-24 10:08:27

只有8个进程。计算唯一进程 ID。

There are only 8 processes. Count the unique process IDs.

壹場煙雨 2024-10-24 10:08:27

我认为添加一个中断而不是添加一个 exit(0) 也可以。

I think adding a break instead of adding an exit(0) would also work.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文