【问题标题】:Understanding how fork() system call works了解 fork() 系统调用的工作原理
【发布时间】:2015-02-21 23:12:44
【问题描述】:

我有这个 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

我做错了什么?

【问题讨论】:

  • fork() != -1 检查什么?
  • 如果调用失败,返回-1。所以我检查调用是否没有失败。
  • 那么else 块有什么作用?
  • e9s 是由于倒退的printfs。将\n 放在printfs 的末尾可以解决这个问题。
  • @Oliver Charlesworth 好吧,现在我看到了问题:如果调用失败,if 语句变为 false,然后else 语句将被执行。

标签: c unix process fork pid


【解决方案1】:

为了了解 Fork 系统调用如何工作的详细功能? 你可以去这个链接: http://linuxtrainers.wordpress.com/2014/12/31/how-fork-system-call-works-what-is-shared-between-parent-and-child-process/

【讨论】:

    【解决方案2】:

    来自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.
    }
    

    圣诞快乐 :)

    【讨论】:

    • 我喜欢圣诞节,但我不会嫁给它。 ;v) 不过,祝你圣诞快乐
    • 哈哈谢谢 :-D 我不是你可能猜到的母语人士 ;)
    • 为代码而来,并留下来参加免费的语法课 :) +1
    【解决方案3】:

    这条线不是你想的那样:

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

    这对父母和孩子都会成功(只要fork 是可能的,几乎总是这样)。您的意思是在这里针对 0 进行测试。父母将获得0,孩子将获得> 0。 -1 是一个错误。

    在您的情况下,除非出现错误,否则不应执行您标记为“子”腿的内容。我不认为那是你的意思。您看到的是最初的 2 个(父子和子)分叉加上 4 个(父+子 * 2)第二个分叉。那是 6 个分叉,这就是输出所指示的。

    【讨论】:

      猜你喜欢
      • 2019-06-09
      • 1970-01-01
      • 1970-01-01
      • 2016-02-29
      • 2016-02-20
      • 2012-12-11
      • 2011-02-18
      • 2018-02-17
      • 1970-01-01
      相关资源
      最近更新 更多