goroutine

  • 轻量级"线程"
  • 非抢占式多任务处理,由协程主动交出控制权
func main() {
	for i := 0; i < 1000; i++ {
		go func(i int) {
			//没有主动交出控制权
			for {
				fmt.Printf("Hello from "+
					"goroutine %d\n", i)
			}
		}(i)
	}
	time.Sleep(time.Minute)
}

主动交出控制权
runtime.Gosched()

  • 编译器/解释器/虚拟机层面的多任务
  • 多个协程可能在一个或多个线程上运行
  • go run -race ***.go
    检测数据访问冲突
func main() {
	for i := 0; i < 100; i++ {
		go func() {
			var a []int
			//没有主动交出控制权
			for {
				/* fmt.Printf("Hello from "+
				"goroutine %d\n", i) */
				a[i]++
				runtime.Gosched()
			}
		}()
	}
	time.Sleep(time.Second)
}

go run -race goroutine.go

[root@localhost goroutine]# go run -race goroutine.go 
==================
WARNING: DATA RACE
Read at 0x00c00011c000 by goroutine 6:
  main.main.func1()
      /opt/goprojects/src/lang/goroutine/goroutine.go:24 +0x38

Previous write at 0x00c00011c000 by main goroutine:
  main.main()
      /opt/goprojects/src/lang/goroutine/goroutine.go:17 +0xa4

Goroutine 6 (running) created at:
  main.main()
      /opt/goprojects/src/lang/goroutine/goroutine.go:18 +0x7e
==================
panic: runtime error: index out of range [2] with length 0

goroutine 19 [running]:
main.main.func1(0xc00011c000)
        /opt/goprojects/src/lang/goroutine/goroutine.go:24 +0x48
created by main.main
        /opt/goprojects/src/lang/goroutine/goroutine.go:18 +0x7f
exit status 2
  • 调度器
  1. 任何函数只需加上go就能送给调度器运行
  2. 不需要在定义时区分是否是异步函数
  3. 调度器在合适的点进行切换
    切换点
    1)I/O,select
    2) channel
    3) 等待锁
    4)函数调用(有时)
    5) runtime.Gosched()
posted @ 2021-11-15 15:34  wangzhilei  阅读(84)  评论(0编辑  收藏  举报