C语言 了解fork()系统调用的工作原理

egdjgwm8  于 2022-12-26  发布在  其他
关注(0)|答案(3)|浏览(122)

我有这个C代码序列:

printf("\nThe PID of this (main) process is: %d\n", getpid());

    if(fork() != -1) { // #1
        printf("\n\nParent 1 PID: %d\n", getpid());
        for(int i = 0; i < 10; i++) {
            printf("\n%d", i);
        }

        if(fork() != -1) { // #2
            //sleep(1);
            printf("\n\nParent 2 PID: %d\n", getpid());
            for(char i = 'a'; i != 'f'; i++) {
                printf("\n%c", i);
            }
        }
        else { // #3
            sleep(3);
            printf("\n\nChild 2 PID: %d\n", getpid());
            for(char i = 'F'; i != 'J'; i++) {
                printf("\n%c", i);
            }
        }
    }
    else { // #4
        sleep(4);
        printf("\n\nChild 1 PID: %d\n", getpid());
        for(int i = 10; i < 20; i++) {
            printf("\n%d", i);
        }
    }

我预计我将有4个过程:两个父进程和两个子进程。在第1行,我第一次调用fork(),从第1行到第4行的所有内容都将在第一个父进程中执行。在父进程(1)中,我再次调用fork(),因此从第2行到第3行,我将有父进程2,从第3行到第4行,我将有子进程2。
我希望打印的内容:

Parent 1 PID: ....
0
1
2
3
4
5
6
7
8
9
Parent 2 PID: ....
a
b
c
d
e
Child 2 PID: ....
F
G
H
I
Child 1 PID: ....
10
11
12
13
14
15
16
17
18
19

我实际得到的是:

Parent 1 PID: 3877

0
1
2
3
4
5
6
7
8

Parent 1 PID: 3878

0
1
2
3
4
5
6
7
8
9

Parent 2 PID: 3877

a
b
c
d
e9

Parent 2 PID: 3878
9

a
b
c
d
Parent 2 PID: 3879

a
b
c
d
e9

eParent 2 PID: 3880

a
b
c
d
e

我做错了什么?

mcvgt66p

mcvgt66p1#

这条线并不是你想的那样:

if(fork() != -1) { // #1

这对父代和子代都是成功的(只要fork是可能的,几乎总是这样)。您的意思是在这里测试0。父代将得到0,子代将得到〉0。-1是错误的。
在您的例子中,标记为“child”的分支不应该被执行,除非出现错误。我不认为这是您的意思。您看到的是最初的2个(父分支和子分支)fork加上4个(父分支+子分支 * 2)第二个fork。这是6个fork,这是输出所指示的。

wnavrhmk

wnavrhmk2#

man fork开始:

RETURN VALUE
       On success, the PID of the child process is returned in the parent, and 0 is returned in the child.  On failure, -1 is returned in the parent, no child process is created, and errno
       is set appropriately.

这意味着,子进程中应该是0,父进程中应该是查尔兹的pid,因此代码应该如下所示:

switch(pid = fork()) {
  case -1:  //error handling here
  case 0:   // child process code here
  default:  // parent process code here.
}

相关问题