zoukankan      html  css  js  c++  java
  • Golang协程实现流量统计系统(2)

     从进程开始,搜索和理解进程

    Google 搜索关键词: C fork example

    什么是fork

    Fork系统调用用于创建一个称为子进程的新进程,该子进程与进行fork()调用的进程(父进程)同时运行。

    创建新的子进程后,两个进程都将在fork()系统调用之后执行下一条指令。

    子进程使用与父进程相同的pc(程序计数器),相同的CPU寄存器,相同的打开文件。

    fork返回值

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

    负值:创建子进程失败。

    零:返回到新创建的子进程。

    正值:返回给父级或调用者。该值包含新创建的子进程的进程ID。

    写点代码

    光看上面的解释有点干,来份代码

    #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!

    执行fork函数后,父进程和子进程都会执行下一行代码和后面的代码,所以会输出两遍

    计算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

    第二个fork函数创建的进程:P2、P3

    第三个fork函数创建的进程:P4、P5、P6、P7

    预测以下程序的输出

    #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,并向父进程返回正整数。

    在这里,两个输出都是可能的,因为父进程和子进程正在同时运行。 因此,我们不知道操作系统是首先控制父进程还是子进程。

    父进程和子进程正在运行同一程序,但这并不意味着它们是相同的。 OS为这两个进程分配不同的数据和状态,并且控制这些进程的流可以有所不同。

    看下面的例子:

    #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

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

    参考阅读: 

    1、https://www.geeksforgeeks.org/fork-system-call/

  • 相关阅读:
    iframe的两种通信方式,iframe的history的优先级
    React-router 将弹框Modal嵌入路由(create a modal route with react-router)
    vue 项目构建 + webpack
    vue 生命周期,v-bind 和 v-on的区别(或 : 和 @的区别),以及父传子、子传父的值传递方式
    linux上配置Sonar代码扫描
    玩转jenkins
    程序小猿的rpa----艺赛旗阶段
    学习完level3加入了uipath家庭,欢迎交流学习。小清风的rpa
    程序员小时光的rpa成长之路(艺赛旗)
    数学期望
  • 原文地址:https://www.cnblogs.com/xinrong2019/p/11838950.html
Copyright © 2011-2022 走看看