zoukankan      html  css  js  c++  java
  • Golang runtime 浅析

    Golang runtime 浅析

    2012-07-19 15:05 by 轩脉刃, 284 阅读, 0 评论, 收藏编辑

    从Goroot的代码出发,里面有很多代码非常复杂,一点点看吧。最重要的概念就是runtime,golang的程序都是在runtime的基础上运行的(除了与底层直接交互的syscall)。

    Runtime

    在$goroot/pkg/runtime/中有三个文件非常重要:

    proc.c

    stack.h

    runtime.h

    在runtime.h中你能看到许多的数据结构和接口

    这里的数据结构就是go中的各种特定的结构对应的底层实现,比如slice:

    1
    2
    3
    4
    5
    6
    7
    struct  Slice
    {               // must not move anything
        byte*   array;      // actual data
        uint32  len;        // number of elements
        uint32  cap;        // allocated number of elements
     
    };

    其中还有两个重要的结构:

    G

    G代表的是goroutine。开启一个goroutine实际就是实例化一个G

    M

    M代表的是Machine。M中存放go程序和机器CPU交互的数据结构

    比如一个双核CPU,在主routine外开启了4个goroutine,那么实际上就有2个M结构,6个G结构(1个是主routine,4个开启的routine,最后一个是闲置的routine)

    runtime和C标准库起的作用是一样的。都是为了语言的跨平台性。runtime可以运行在Windows和Unix平台,可以运行在Intel或ARM处理器上。

    clip_image001[4]

    一个go程序都附带一个Runtime,runtime负责与底层操作系统交互。

    这篇文章给了一个清晰的runtime概念:http://pastebin.com/LEsB8FVW

    启动流程

    回到$goroot/pkg/runtime/proc.c

    里面这么个注释:

    // The bootstrap sequence is:

    //

    // call osinit

    // call schedinit

    // make & queue new G

    // call runtime·mstart

    //

    // The new G calls runtime·main.

    明确告诉我们go程序的启动流程是:

    1 调用osinit,操作系统级别的初始化

    2 调用runtime·schedinit

    在这个函数内做了许多预操作

    获取程序运行参数

    获取程序环境变量

    (主要是有一个环境变量GOMAXPROCS,你可以使用runtime.GOMAXPROCS(int) 或者直接设置环境变量$GOMAXPROCS改变程序使用的CPU数量)

    3 调用runtime·mstart启动M

    4 调用runtime·main

    在runtime.main中有这么两行:

    main·init(); //调用main包中的init函数

    main·main(); //调用main包中的main函数

    用gdb调试看trace看到调用栈

    clip_image002[4]

    关于启动流程推荐一下这篇文章:http://www.cnblogs.com/genius0101/archive/2012/04/16/2447147.html

    go中调用C程序

    go中是可以调用C程序的,有两种方法:

    1 go程序使用import "C"

    2 使用文件.goc(以前也叫做cgo)

    第一种方法

    例子:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    package main
     
    /*
    #include <stdlib.h>
    */
    import "C"
     
    import "fmt"
     
    func main(){
        fmt.Println(int(C.random()))
    }
     
    func Seed(i int) {
        C.srandom(C.uint(i))
     
    }</stdlib.h>

    运行

    clip_image003[4]

    使用起来非常简单,import "C"之后就有一个全局变量大写C就包含了C库中的函数, include的c库作为注释放在import "C"上面

    更多可以参考:

    http://golang.org/doc/articles/c_go_cgo.html

    http://golang.org/cmd/cgo/

    第二种方法

    直接创建goc文件,goc文件是C和go混合编写的文件

    参照$goroot/src/pkg/runtime/syscall_windows.goc

    clip_image004[4]

    这种方式不允许include C的标准库,只能引用自定义的头文件。这种方式很少使用,基本只需要知道一下就好了。

    参考文章

    我之前写了文章把所有golang的底层相关文章列出来了

    http://www.cnblogs.com/yjf512/archive/2012/07/17/2595689.html

    如果有更多的好资料麻烦各位贴出来下~

    Creative Commons License

    本文基于署名-非商业性使用 3.0许可协议发布,欢迎转载,演绎,但是必须保留本文的署名叶剑峰(包含链接http://www.cnblogs.com/yjf512/),且不得用于商业目的。如您有任何疑问或者授权方面的协商,请与我联系

    分类: Go
  • 相关阅读:
    SQL性能优化(不断总结)
    字符编码:区位/国标(gb2312、gbk)/机内码/ASCII/ANSI/Big5
    计算机中信息编码
    删除sybase一列报错:The 'select into' database option is not enabled for database.....
    常用Oracle函数(From OTN)
    常用正则
    剖析Windows的消息运行机制 (学习一)
    服务器响应码及解释
    了解注册表结构
    Windows消息大全收藏
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/2599949.html
Copyright © 2011-2022 走看看