上面是启动过程,看一下退出过程:
当 main 函数执行结束之后,会执行 exit(0) 来退出进程 。若执行 exit(0) 后,进程没有退出,main 函数最后的代码会一直访问非法地址:
exit(0) for {var x *int32*x = 0}
正常情况下,一旦出现非法地址访问,系统会把进程杀死,用这样的方法确保进程退出 。
关于程序退出这一段的阐述来自群聊《golang runtime 阅读》,又是一个高阶的读源码的组织,Github 主页见参考资料 。
当然 Go 程序启动这一部分其实还会涉及到 fork 一个新进程、装载可执行文件,控制权转移等问题 。还是推荐看前面的两本书,我觉得我不会写得更好,就不叙述了 。
4.GoRoot 和 GoPath
GoRoot 是 Go 的安装路径 。mac 或 unix 是在 /usr/local/go 路径上,来看下这里都装了些什么:
文章插图
bin 目录下面:
文章插图
pkg 目录下面:
文章插图
Go 工具目录如下,其中比较重要的有编译器 compile,链接器 link:
文章插图
GoPath 的作用在于提供一个可以寻找 .go 源码的路径,它是一个工作空间的概念,可以设置多个目录 。Go 官方要求,GoPath 下面需要包含三个文件夹:
src pkgbin
src 存放源文件,pkg 存放源文件编译后的库文件,后缀为 .a;bin 则存放可执行文件 。5.Go 命令详解
直接在终端执行:
go
就能得到和 go 相关的命令简介:文章插图
和编译相关的命令主要是:
go build go installgo run
go buildgo build 用来编译指定 packages 里的源码文件以及它们的依赖包,编译的时候会到 $GoPath/src/package 路径下寻找源码文件 。go build 还可以直接编译指定的源码文件,并且可以同时指定多个 。
通过执行 go help build 命令得到 go build 的使用方法:
usage: go build [-o output] [-i] [build flags] [packages]
-o 只能在编译单个包的时候出现,它指定输出的可执行文件的名字 。-i 会安装编译目标所依赖的包,安装是指生成与代码包相对应的 .a 文件,即静态库文件(后面要参与链接),并且放置到当前工作区的 pkg 目录下,且库文件的目录层级和源码层级一致 。
至于 build flags 参数, build,clean,get,install,list,run,test 这些命令会共用一套:
文章插图
我们知道,Go 语言的源码文件分为三类:命令源码、库源码、测试源码 。
- 命令源码文件:是 Go 程序的入口,包含 func main 函数,且第一行用 packagemain 声明属于 main 包 。
- 库源码文件:主要是各种函数、接口等,例如工具类的函数 。
- 测试源码文件:以 _test.go 为后缀的文件,用于测试程序的功能和性能 。
我们通过一个很简单的例子来演示 go build 命令 。我用 Goland 新建了一个 hello-world 项目(为了展示引用自定义的包,和之前的 hello-world 程序不同),项目的结构如下:
文章插图
最左边可以看到项目的结构,包含三个文件夹:bin,pkg,src 。其中 src 目录下有一个 main.go,里面定义了 main 函数,是整个项目的入口,也就是前面提过的所谓的命令源码文件;src 目录下还有一个 util 目录,里面有 util.go 文件,定义了一个可以获取本机 IP 地址的函数,也就是所谓的库源码文件 。
中间是 main.go 的源码,引用了两个包,一个是标准库的 fmt;一个是 util 包,util 的导入路径是 util 。所谓的导入路径是指相对于 Go 的源码目录 $GoRoot/src 或者 $GoPath/src 的下的子路径 。例如 main 包里引用的 fmt 的源码路径是 /usr/local/go/src/fmt,而 util 的源码路径是 /Users/qcrao/hello-world/src/util,正好我们设置的 GoPath = /Users/qcrao/hello-world 。
最右边是库函数的源码,实现了获取本机 IP 的函数 。
在 src 目录下,直接执行 go build 命令,在同级目录生成了一个可执行文件,文件名为 src,使用 ./src 命令直接执行,输出:
hello world! Local IP: 192.168.1.3
推荐阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 详解3种区别Linux服务器是物理机或者虚拟机的方法
- 详解Docker可视化管理工具shipyard--部署教程及功能展示
- 绝对经典,看了必会 linux中部署mysql主从同步示例详解
- 详解Oracle数据库物理设计--表和索引设计建议
- 详解微服务技术中进程间通信
- ”什么是内网穿透“详解
- 局域网中NAT具体工作过程详解
- MySQL执行计划命令EXPLAIN详解
- 静态路由详解
- 计算机启动过程详解