Go 并发

优质
小牛编辑
150浏览
2023-12-01

Go 在语言级别支持协程(多数语言在语法层面并不直接支持协程),叫做 goroutine.

人们把 Go 语言称之为 21 世纪的C语言,第一是因为 Go 语言设计简单,第二是因为21世纪最重要的就是并行程序设计,而Go从语言层面就支持并发和并行

Go 并发小案例

package main

import (
	"fmt"
	"time"
)

func sing()  {
	for i:=0; i< 10; i++{
		fmt.Println("我在唱歌")
		time.Sleep(time.Millisecond)
	}
}
func dance() {
	for i:=0; i< 10; i++{
		fmt.Println("我在跳舞---")
		time.Sleep(time.Millisecond)
	}
}

func main() {
	// 串行: 必须先唱完歌才能跳舞
	//sing()
	//dance()

	// 并行: 可以边唱歌, 边跳舞
	// 注意点: 主线程不能死, 否则程序就退出了
	go sing() // 开启一个协程
	go dance() // 开启一个协程
	for{
		;
	}
}

runtime 包中常用的函数

Gosched:使当前 go 程放弃处理器,以让其它 go 程运行

  package main
  import (
  	"fmt"
  	"runtime"
  )
  
  func sing()  {
  	for i:=0; i< 10; i++{
  		fmt.Println("我在唱歌")
  		// Gosched使当前go程放弃处理器,以让其它go程运行。
  		// 它不会挂起当前go程,因此当前go程未来会恢复执行
  		runtime.Gosched()
  	}
  }
  func dance() {
  	for i:=0; i< 10; i++{
  		fmt.Println("我在跳舞---")
  		runtime.Gosched()
  	}
  }
  
  func main() {
  
  	go sing()
  	go dance()
  	for{
  		;
  	}
  }

Goexit:终止调用它的 go 程,其它 go 程不会受影响

  package main
  import (
  	"fmt"
  	"runtime"
  )
  
  func main() {
  	go func() {
  		fmt.Println("123")
  		// 退出当前协程
  		//runtime.Goexit()
  		// 退出当前函数
  		//return
  		test()
  		fmt.Println("456")
  	}()
  	for{
  		;
  	}
  }
  
  func test()  {
  	fmt.Println("abc")
  	// 只会结束当前函数, 协程中的其它代码会继续执行
  	//return
  	// 会结束整个协程, Goexit之后整个协程中的其它代码不会执行
  	runtime.Goexit()
  	fmt.Println("def")
  }

NumCPU:返回本地机器的逻辑 CPU 个数

  package main
  import (
  	"fmt"
  	"runtime"
  )
  func main() {
  	num := runtime.NumCPU()
  	fmt.Println(num)
  }

GOMAXPROCS:设置可同时执行的最大 CPU 数,并返回先前的设置

  • Go 语言 1.8 之前,需要我们手动设置
  • Go 语言 1.8 之后,不需要我们手动设置
  func main() {

  	// 获取带来了CPU个数
  	num := runtime.NumCPU()
  	// 设置同时使用CPU个数
  	runtime.GOMAXPROCS(num)
  }