1、简单的使用关键字 go + 函数调用实现并发

示例1:

  1. func taskA(){
  2. fmt.Println("A")
  3. }
  4. func taskB(){
  5. fmt.Println("B")
  6. }
  7. func main(){
  8. fmt.Println(time.Now())
  9. go taskA()
  10. go taskB()
  11. fmt.Println(time.Now())
  12. }

结果:

结果为空原因:主例程退出,子例程也会退出,即使工作例程没有执行完。
以上代码一种最简单,但比较low的解决方法是使用time.Sleep();这种方式可以用于测试,但不能用于实际的应用编写。如下:

  1. func taskA(){
  2. fmt.Println("A")
  3. }
  4. func taskB(){
  5. fmt.Println("B")
  6. }
  7. func main(){
  8. fmt.Println(time.Now())
  9. go taskA()
  10. go taskB()
  11. fmt.Println(time.Now())
  12. time.Sleep(time.Microsecond * 1000)
  13. }
2、runtime包

可以使用runtime包中的Gosched()方法让函数调用,让出cpu调度给其他例程使用。
示例:

  1. import "runtime"
  2. func taskA(){
  3. for i:=1 ;i<=10;i++{}
  4. fmt.Println("A")
  5. runtime.Gosched()
  6. }
  7. }
  8. func taskB(){
  9. for i:=1;i<=10;i++{}
  10. fmt.Println("B")
  11. runtime.Gosched()
  12. }
  13. }
  14. func main(){
  15. fmt.Println(time.Now())
  16. go taskA()
  17. go taskB()
  18. fmt.Println(time.Now())
  19. time.Sleep(time.Microsecond * 1000)
  20. }

结果,为函数taskA和函数TaskB,穿插这着执行

3、waitgroup,例程间通信(计数信号量)

例程计数信号量:
启动例程之前,信号量+1
当例程执行结束时,信号量-1
当信号量非阻塞主例程结束,当信号量为0时主例程结束。

我们可以”sync”包的 waitgroup 来实现这一功能

示例:

  1. package main
  2. import (
  3. "fmt"
  4. "runtime"
  5. "sync"
  6. )
  7. func taskA(a *sync.WaitGroup){
  8. for i :=0;i<=10;i++{
  9. fmt.Println(i)
  10. runtime.Gosched()
  11. }
  12. a.Done() //或 defer a.Done()
  13. }
  14. func taskB(a *sync.WaitGroup){
  15. for i :=0;i<=10;i++{
  16. fmt.Println(i)
  17. runtime.Gosched()
  18. }
  19. a.Done() //或 defer a.Done()
  20. }
  21. func main(){
  22. fmt.Println("start")
  23. //sync.WaitGroup 是一个结构体,这个结构体只有三个方法 “Add” “Done” “Wait”
  24. //Add 信号量+1
  25. //Done 信号量-1
  26. //wait 信号量为0,允许结束主例程
  27. var wg sync.WaitGroup
  28. go taskA(*wg)
  29. go taskB(*wg)
  30. wg.Wait()
  31. fmt.Println("end")
  32. }
文档更新时间: 2021-08-21 14:26   作者:张尚