最近在学习了go 语言 , 正好学习到了 协程这一块 ,遇到了困惑的地方.这个是go语言官方文档 . 在我的理解当中是,协程只能在主线程释放时间片后才会经过系统调度来运行协程,其实正确的也确实是这样的,但是我遇到了协程强占主线程的一个问题,经过帮助,现在已经了解.废话不多说,先看代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
| package main import ( "fmt" "time" ) func main() { go say("world") say("hello") fmt.Println("---------------1") a := []int{7, 2, 8, -9, 4, 0} fmt.Println("===", a[:len(a)/2]) c := make(chan int) go sum(a[:len(a)/2], c) go sum(a[len(a)/2:], c) x, y := <-c, <-c // receive from c fmt.Println(x, y, x+y) fmt.Println("---------------2") c2 := make(chan int, 2) c2 <- 1 c2 <- 2 fmt.Println(<-c2) fmt.Println(<-c2) fmt.Println("---------------3") c3 := make(chan int, 10) go fibonacci(cap(c3), c3) for i := range c3 { fmt.Println(i) } fmt.Println("---------------4") c4 := make(chan int) quit := make(chan int) go func() { for i := 0; i < 10; i++ { fmt.Println(<-c4) } quit <- 0 }() fibonacci2(c4, quit) fmt.Println("---------------5") tick := time.Tick(100 * time.Millisecond) boom := time.After(500 * time.Millisecond) for { select { case <-tick: fmt.Println("tick. ") case <-boom: fmt.Println("BOOM!") return default: fmt.Println(" .") time.Sleep(50 * time.Millisecond) } }*/ } func say(s string) { for i := 0; i < 5; i++ { time.Sleep(100 * time.Millisecond) fmt.Println(s) } }
|
先看两次代码运行结果
第一次: (结合上面代码查看打印顺序)

第二次:(结合第一次查看打印顺序)

是不是发现了每次的打印顺序是不同的
这个就是协程强占执行
我们先来看下它的执行循序 , 主线程运行====>释放时间片====>协程运行==>释放时间片====>主线程运行
根据这段代码
我们知道,这个是属于主线程里面的,所以优先执行(注意实参是”hello”)
然后看看 say 方法
1 2 3 4 5 6
| func say(s string) { for i := 0; i < 5; i++ { time.Sleep(100 * time.Millisecond) fmt.Println(s) } }
|
当执行到循环里面的
1
| time.Sleep(100 * time.Millisecond)
|
会释放时间片,同时 暂停执行代码,系统调度到协程
也是同一个方法,同时也会执行
1
| time.Sleep(100 * time.Millisecond)
|
释放时间片
于是再打印的时候就会出现强占执行