C中的fork()

Fork系统调用用于创建一个名为 子进程 ,它与进行fork()调用的进程(父进程)同时运行。创建新的子进程后,两个进程都将执行fork()系统调用之后的下一条指令。子进程使用与父进程相同的pc(程序计数器)、相同的CPU寄存器和相同的打开文件。

null

它不接受任何参数,并返回一个整数值。下面是fork()返回的不同值。

负值 :创建子进程失败。 :返回到新创建的子进程。 正值 :返回给家长或呼叫者。该值包含新创建的子进程的进程ID。

creating a fork process

请注意,以上程序不在Windows环境下编译。

  1. 预测以下程序的输出: .

    #include <stdio.h>
    #include <sys/types.h>
    #include <unistd.h>
    int main()
    {
    // make two process which run same
    // program after this instruction
    fork();
    printf ( "Hello world!" );
    return 0;
    }

    
    

    输出:

    Hello world!
    Hello world!
    
  2. 计算hello的打印次数:

    #include <stdio.h>
    #include <sys/types.h>
    int main()
    {
    fork();
    fork();
    fork();
    printf ( "hello" );
    return 0;
    }

    
    

    输出:

    hello
    hello
    hello
    hello
    hello
    hello
    hello
    hello
    

    打印“hello”的次数等于创建的进程数。进程总数=2 N ,其中n是fork系统调用的数量。这里n=3,2 3. = 8

    让我们为这三行加上一些标签名称:

    fork ();   // Line 1
    fork ();   // Line 2
    fork ();   // Line 3
    
           L1       // There will be 1 child process 
        /          // created by line 1.
      L2      L2    // There will be 2 child processes
     /      /     //  created by line 2
    L3  L3  L3  L3  // There will be 4 child processes 
                    // created by line 3
    
    

    所以总共有八个进程(新的子进程和一个原始进程)。

    如果我们想将流程之间的关系表示为一个树层次结构,它将如下所示:

    主要过程:P0 由第一个fork创建的进程:P1 第二个分支创建的进程:P2、P3 第三个分支创建的流程:P4、P5、P6、P7

                 P0
             /   |   
           P1    P4   P2
          /            
        P3    P6         P5
       /
     P7
    
  3. 预测以下程序的输出:

    #include <stdio.h>
    #include <sys/types.h>
    #include <unistd.h>
    void forkexample()
    {
    // child process because return value zero
    if (fork() == 0)
    printf ( "Hello from Child!" );
    // parent process because return value non-zero.
    else
    printf ( "Hello from Parent!" );
    }
    int main()
    {
    forkexample();
    return 0;
    }

    
    

    输出:

    1.
    Hello from Child!
    Hello from Parent!
         (or)
    2.
    Hello from Parent!
    Hello from Child!
    

    在上面的代码中,创建了一个子进程。fork()在子进程中返回0,在父进程中返回正整数。 在这里,两个输出是可能的,因为父进程和子进程同时运行。所以我们不知道操作系统是先控制父进程还是子进程。

    重要事项: 父进程和子进程运行相同的程序,但这并不意味着它们是相同的。操作系统为这两个进程分配不同的数据和状态,这些进程的控制流程可能会有所不同。请参见下一个示例:

  4. 预测以下程序的输出:

    #include <stdio.h>
    #include <sys/types.h>
    #include <unistd.h>
    void forkexample()
    {
    int x = 1;
    if (fork() == 0)
    printf ( "Child has x = %d" , ++x);
    else
    printf ( "Parent has x = %d" , --x);
    }
    int main()
    {
    forkexample();
    return 0;
    }

    
    

    输出:

    Parent has x = 0
    Child has x = 2
         (or)
    Child has x = 2
    Parent has x = 0
    

    在这里,一个过程中的全局变量变化不会影响其他两个过程,因为两个过程的数据/状态不同。而且父级和子级同时运行,因此两个输出都是可能的。

fork()与exec()的比较

fork系统调用创建一个新进程。fork()创建的新进程是当前进程的副本,返回值除外。exec()系统调用用新程序替换当前进程。

练习:

  1. 进程执行以下代码:

    for (i = 0; i < n; i++)
    fork();

    
    

    创建的子进程总数为:(GATE-CS-2008) (A) n (B) 2^n–1 (C) 2^n (D) 2^(n+1)–1;

    看见 寻求解决方案。

  2. 考虑下面的代码片段:

    if (fork() == 0) {
    a = a + 5;
    printf ( "%d, %d" , a, &a);
    }
    else {
    a = a –5;
    printf ( "%d, %d" , a, &a);
    }

    
    

    假设u,v是父进程打印的值,x,y是子进程打印的值。以下哪一项是正确的?(GATE-CS-2005) (A) u=x+10,v=y (B) u=x+10和v!=Y (C) u+10=x和v=y (D) u+10=x和v!=Y 看见 寻求解决方案。

  3. 预测以下程序的输出。

    #include <stdio.h>
    #include <unistd.h>
    int main()
    {
    fork();
    fork() && fork() || fork();
    fork();
    printf ( "forked" );
    return 0;
    }

    
    

    看见 寻求解决方案

相关文章: C程序演示fork()和pipe() C语言中的僵尸进程和孤儿进程 fork()和使用它创建的内存共享b/w进程。

参考资料: http://www.csl.mtu.edu/cs4411.ck/www/NOTES/process/fork/create.html

本文由 极客队 卡丹·帕特尔 .如果你喜欢GeekSforgek,并想贡献自己的力量,你也可以使用 贡献极客。组织 或者把你的文章寄到contribute@geeksforgeeks.org.看到你的文章出现在Geeksforgeks主页上,并帮助其他极客。

如果您发现任何不正确的地方,或者您想分享有关上述主题的更多信息,请写下评论。

© 版权声明
THE END
喜欢就支持一下吧
点赞10 分享