参考链接

  1. 使用文本编辑器创建 Go 程序;
  2. 保存文件;
  3. 编译程序;
  4. 运行编译得到的可执行文件。

特性

  • 并发模型:运行时用 Goroutine 运行所有的一切,Go语言从底层原生支持并发
  • 内存分配: Go 选择了 tcmalloc,它本就是为并发而设计的高性能内存分配组
  • 垃圾回收:指针运算被阻止

goroutine

goroutine类似于线程,但并非线程。可以将 goroutine 理解为一种虚拟线程。Go语言运行时会参与调度 goroutine,并将 goroutine 合理地分配到每个 CPU 中,最大限度地使用 CPU 性能。

多个 goroutine 中,Go语言使用通道(channel)进行通信,通道是一种内置的数据结构,可以让用户在不同的 goroutine 之间同步发送具有类型的消息。这让编程模型更倾向于在 goroutine 之间发送消息,而不是让多个 goroutine 争夺同一个数据的使用权。

简介 - 图1

  1. package main
  2. import (
  3. "fmt"
  4. "math/rand"
  5. "time"
  6. )
  7. // 数据生产者
  8. func producer(header string, channel chan<- string) {
  9. // 无限循环, 不停地生产数据
  10. for {
  11. // 将随机数和字符串格式化为字符串发送给通道
  12. channel <- fmt.Sprintf("%s: %v", header, rand.Int31())
  13. // 等待1秒
  14. time.Sleep(time.Second)
  15. }
  16. }
  17. // 数据消费者
  18. func customer(channel <-chan string) {
  19. // 不停地获取数据
  20. for {
  21. // 从通道中取出数据, 此处会阻塞直到信道中返回数据
  22. message := <-channel
  23. // 打印数据
  24. fmt.Println(message)
  25. }
  26. }
  27. func main() {
  28. // 创建一个字符串类型的通道
  29. channel := make(chan string)
  30. // 创建producer()函数的并发goroutine
  31. go producer("cat", channel)
  32. go producer("dog", channel)
  33. // 数据消费函数
  34. customer(channel)
  35. }

代码分析

  1. 03 行,导入格式化(fmt)、随机数(math/rand)、时间(time)包参与编译。
  2. 10 行,生产数据的函数,传入一个标记类型的字符串及一个只能写入的通道。
  3. 13 行,for{} 构成一个无限循环。
  4. 15 行,使用 rand.Int31() 生成一个随机数,使用 fmt.Sprintf() 函数将 header 和随机数格式化为字符串。
  5. 18 行,使用 time.Sleep() 函数暂停 1 秒再执行这个函数。如果在 goroutine 中执行时,暂停不会影响其他 goroutine 的执行。
  6. 23 行,消费数据的函数,传入一个只能写入的通道。
  7. 26 行,构造一个不断消费消息的循环。
  8. 28 行,从通道中取出数据。
  9. 31 行,将取出的数据进行打印。
  10. 35 行,程序的入口函数,总是在程序开始时执行。
  11. 37 行,实例化一个字符串类型的通道。
  12. 39 行和第 40 行,并发执行一个生产者函数,两行分别创建了这个函数搭配不同参数的两个 goroutine
  13. 42 行,执行消费者函数通过通道进行数据消费。

安装

https://studygolang.com/dl
https://www.yuque.com/xieguang/kubgyn/lhfi56

hello world

  1. package main
  2. import "fmt"
  3. func main() {
  4. fmt.Println("Hello, World!")
  5. }