GO基础(2) | 青训营笔记

119 阅读3分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 2 天

一.本堂课重点内容

本节课讲了讲goroutine的特点,简略概述了channel方法,还有go语言项目的配置特点以及test方法

二.详细知识点介绍

1.goroutine:

携程coroutine,一种轻量级线程,作用在用户态,切换时不需要进入内核态,相比于线程栈(MB级别),携程栈只有KB级别,一个线程中可以有任意多个携程

goroutine可以说是go语言最大的特点之一,Go在语言级别支持携程,标准库提供所有系统调用操作,同步IO操作,大大减少了切换时对系统的依赖

携程调度:关于coroutine(goroutine)的调度,指将多个携程调度给有需要的线程,经过携程调度器的控制,使得用户态的携程可以为内核态的线程分担工作(M-N对应)

goroutine机制的结构:对于系统全局队列有一定数量的gorooutine,而每个线程都有一定数量的携程,其中系统保有一定数量的processor(GOMAXPROCS个),每个processor带有一个本地队列,保存分配指当前processor的携程,由此processor可以将这些携程分配给thread进行工作,也可以用一些方法将这些goroutine在thread间分配

image.png

对于goroutine的调度,有work stealing、hand off等机制,这里就不详细介绍了

goroutine的创建:在函数前面加上go关键字即可

如:

func goTask() {
    //携程代码
}
 
func main() {
    //创建一个 goroutine,启动另外一个任务
    go ngoTask()
}

2.channel:

go语言中一种核心类型,类似管道,是goroutine之间进行通信的重要方式

创建语句 管道名 := make(chan 管道类数据类型)

其中分为有缓冲管道和无缓冲管道,可在创建管道时预分配空间来创建有缓冲管道

管道名 := make(chan 管道数据类型, 容量)

关于管道有无缓冲的概念,类似于锁概念中条件变量或计数器等,表示channel内能暂存的数据量,可以使用channel进行goroutine之间的同步

3.Go Modules

go语言的依赖解决方案,可以使用go mod命令来管理依赖方案

其中比较重要的模块如GOPROXY,用于设置go模块代理和镜像拉取;GOSUMDB确保拉取数据未篡改等

关于go modules 我目前还没怎么用过,先总结一下基本的操作

(1)初始化

在创建完项目目录后,执行命令go mod init 模块导入路径,如github.com/xxx

然后在根目录创建main.go文件,导入模块

package main

import (
    "fmt"
    "github.com/xxx"//模块路径
)

(2)go.mod文件

文件内的的关键字

module: 用于定义当前项目的模块路径

go:标识当前Go版本.即初始化版本

require: 当前项目依赖的一个特定的必须版本

// indirect: 示该模块为间接依赖,也就是在当前应用程序中的 import 语句中,并没有发现这个模块的明确引用,有可能是你先手动 go get 拉取下来的,也有可能是你所依赖的模块所依赖的.

三.实践练习例子

讲了关于项目测试的一些规范

关于go项目实战,课程展示了社区话题页面需求以及构建的例子

实现了后端的本地web服务,话题和回帖数用文件存储的功能

四.个人总结

本节课讲了goroutine这个重要特点以及channel方法,对go高并发编程有一定了解

五.引用参考

Using Go Modules - The Go Programming Language

4、Go Modules (yuque.com)