1

我无法理解打印输出的顺序......

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

int main(void)
{
    int index;
    for (index = 1; index < 4; index++)
    {
        printf("HI\n"); 
        fork();
    }
    printf("Unix System Programming\n");
    exit(0);
}

很容易理解,当我只打印 unix 编程系统时,fork 工作了 2^n 次……但是当我用它打印 HI 时……我不明白为什么这个顺序?输出:

HI
HI
HI
HI
HI
Unix System Programming
HI
HI
Unix System Programming
Unix System Programming
Unix System Programming
Unix System Programming
Unix System Programming
Unix System Programming
Unix System Programming
4

3 回答 3

2

为了更好的可见性,我刚刚修改了代码

int main(void)   
    {  
        int index;  
        for (index = 1; index < 4; index++)  
        {
            printf("We are in loop with  process id=%d\n",getpid());
            if(!fork()) { //Child process
               printf("Came inside chid with process id=%d\n",getpid());
              // _exit(0);
            } else {     //Parent process
              printf("Came inside parent with process id=%d\n",getpid());
           }
        }
        printf("We are out of loop with  process id=%d\n",getpid());
        exit(0);
    }

    [OP]   
    We are in loop with  process id=2258   -----> Main Parent   
    Came inside parent with process id=2258   
    We are in loop with  process id=2258  
    Came inside child with process id=2259  
    We are in loop with  process id=2259  
    Came inside parent with process id=2258  
    We are in loop with  process id=2258  
    Came inside parent with process id=2259  
    We are in loop with  process id=2259  
    Came inside parent with process id=2258  
    We are out of loop with  process id=2258 ----> "Outer block of loop referring main Parent  Here exit(0) will rip parent process of pid 2258 "      
    Came inside parent with process id=2259     
    We are out of loop with  process id=2259   
    Came inside child with process id=2263   
    We are out of loop with  process id=2263   
    Came inside child with process id=2261   
    We are in loop with  process id=2261   
    Came inside parent with process id=2261   
    We are out of loop with  process id=2261   
    Came inside child with process id=2264   
    We are out of loop with  process id=2264   
    Came inside child with process id=2262   
    Came inside child with process id=2260   
    We are out of loop with  process id=2262   
    We are in loop with  process id=2260   
    Came inside parent with process id=2260   
    We are out of loop with  process id=2260   
    Came inside child with process id=2265   
    We are out of loop with  process id=2265   

首先,我们必须考虑循环执行 3 次,每次 fork 将产生 1 个子节点,并且肯定会有一个父节点,并且执行将完全取决于调度,可能是子节点,也可能是父节点。

一旦你有更多的迭代值,这将变得非常令人头疼。

现在让孩子清洗

    int main(void)   
            {  
                int index;  
                for (index = 1; index < 4; index++)  
                {
                    printf("We are in loop with  process id=%d\n",getpid());
                    if(!fork()) { //Child process
                       printf("Came inside chid with process id=%d\n",getpid());
                       _exit(0);
                    } else {     //Parent process
                      printf("Came inside parent with process id=%d\n",getpid());
                   }
                }
                printf("We are out of loop with  process id=%d\n",getpid());
                exit(0);
            }

    We are in loop with  process id=2393
Came inside parent with process id=2393
We are in loop with  process id=2393
Came inside chid with process id=2394
Came inside parent with process id=2393
We are in loop with  process id=2393
Came inside parent with process id=2393
We are out of loop with  process id=2393
Came inside chid with process id=2396
Came inside chid with process id=2395

所以上面的OP现在更清楚了三倍父和三倍子执行。

于 2013-03-02T13:51:02.770 回答
1

不能保证计算机选择以哪种顺序调度进程,一个进程可以在另一个进程执行单行之前完全执行。

输出的一种可能解释:

列是进程,索引在括号中

"USP" 是 "Unix 系统编程"
"FORK" 是当一个进程分叉时
"CREATE" 是当一个进程被创建时

1      2      3      4      5      6      7      8
HI (1)
FORK   CREATE
HI (2)
FORK          CREATE
       HI (2)
       FORK          CREATE
HI (3)
FORK                        CREATE
                     HI (3)
                     FORK          CREATE
USP
              HI (3)
              FORK                        CREATE
       HI (3)
       FORK                                      CREATE
       USP
              USP
                     USP
                            USP
                                   USP
                                          USP
                                                 USP

以上不太可能是实际输出,因为我们不知道计算机以什么顺序调度进程。您可以在打印语句中添加进程 ID 以指示任何给定输出行属于哪个进程。

于 2013-03-02T11:47:34.647 回答
0

还可以通过查询每个进程的 PID 来更详细地了解正在发生的事情:

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

int main(void)
{
    int index;
    for (index = 1; index < 4; index++)
    {
        printf("HI: pid %d with i=%d will now fork\n", getpid(), index);
        if (0 == fork())
        {
                printf("I am a new process with i=%d and pid=%d\n", index, getpid());
        }
    }
    printf("Unix System Programming from pid %d\n", getpid());
    exit(0);
}

至于 printf()s 的顺序,事实是新进程在完全产生之前需要一个随机时间(很小,几乎为零,但仍然是随机的),并且该时间与父进程产生更多进程并终止所需的时间。

因此,您可能有:

process 1 prints "HI" and spawns process 2
process 2 prints "HI" and...
process 1 prints "HI" and spawns process 3
                             ... spawns process 4
...process 2 terminates ("Unix programming")
...process 3 terminates ("Unix programming")
...process 4 prints "HI"

下一次可能进程 2 在进程 3 生成之前成功打印 HI,依此类推。如果您需要确定性序列,则必须实现某种类型的进程同步。

于 2013-03-02T11:50:49.190 回答