• go 协程与主线程强占运行


    最近在学习了go 语言 ,  正好学习到了 协程这一块 ,遇到了困惑的地方.这个是go语言官方文档 . 在我的理解当中是,协程只能在主线程释放时间片后才会经过系统调度来运行协程,其实正确的也确实是这样的,但是我遇到了协程强占主线程的一个问题,经过帮助,现在已经了解.废话不多说,先看代码

     1 package main
     2 
     3 import (
     4     "fmt"
     5     "time"
     6 )
     7 
     8 func main() {
     9     go say("world")
    10     say("hello")
    11     /*
    12         fmt.Println("---------------1")
    13 
    14         a := []int{7, 2, 8, -9, 4, 0}
    15         fmt.Println("===", a[:len(a)/2])
    16         c := make(chan int)
    17         go sum(a[:len(a)/2], c)
    18         go sum(a[len(a)/2:], c)
    19         x, y := <-c, <-c // receive from c
    20 
    21         fmt.Println(x, y, x+y)
    22 
    23         fmt.Println("---------------2")
    24 
    25         c2 := make(chan int, 2)
    26         c2 <- 1
    27         c2 <- 2
    28         fmt.Println(<-c2)
    29         fmt.Println(<-c2)
    30 
    31         fmt.Println("---------------3")
    32         c3 := make(chan int, 10)
    33         go fibonacci(cap(c3), c3)
    34         for i := range c3 {
    35             fmt.Println(i)
    36         }
    37 
    38         fmt.Println("---------------4")
    39         c4 := make(chan int)
    40         quit := make(chan int)
    41         go func() {
    42             for i := 0; i < 10; i++ {
    43                 fmt.Println(<-c4)
    44             }
    45             quit <- 0
    46         }()
    47         fibonacci2(c4, quit)
    48 
    49         fmt.Println("---------------5")
    50         tick := time.Tick(100 * time.Millisecond)
    51         boom := time.After(500 * time.Millisecond)
    52         for {
    53             select {
    54             case <-tick:
    55                 fmt.Println("tick. ")
    56             case <-boom:
    57                 fmt.Println("BOOM!")
    58                 return
    59             default:
    60                 fmt.Println("    .")
    61                 time.Sleep(50 * time.Millisecond)
    62             }
    63         }*/
    64 }
    65 
    66 func say(s string) {
    67     for i := 0; i < 5; i++ {
    68         time.Sleep(100 * time.Millisecond)
    69         fmt.Println(s)
    70     }
    71 }

    先看两次代码运行结果

    第一次:  (结合上面代码查看打印顺序)

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

    是不是发现了每次的打印顺序是不同的

    这个就是协程强占执行

    我们先来看下它的执行循序 , 主线程运行====>释放时间片====>协程运行==>释放时间片====>主线程运行

    根据这段代码 

    1 say("hello")

    我们知道,这个是属于主线程里面的,所以优先执行(注意实参是"hello")  

    然后看看 say 方法 

    1 func say(s string) {
    2     for i := 0; i < 5; i++ {
    3         time.Sleep(100 * time.Millisecond)
    4         fmt.Println(s)
    5     }
    6 }

    当执行到循环里面的 

    time.Sleep(100 * time.Millisecond)

    会释放时间片,同时 暂停执行代码,系统调度到协程 

    go say("world")

    也是同一个方法,同时也会执行

    time.Sleep(100 * time.Millisecond)

    释放时间片 

    于是再打印的时候就会出现强占执行

  • 相关阅读:
    MAVEN学习-第一个Maven项目的构建
    MAVEN学习笔记-maven的获取和安装
    Hibernate中的锁机制
    java进阶之反射:反射基础之如何获取一个类以及如何获取这个类的所有属性和方法(2)
    java进阶之反射:反射基础之如何获取一个类以及如何获取这个类的所有属性和方法(1)
    java中的文件读取和文件写出:如何从一个文件中获取内容以及如何向一个文件中写入内容
    开篇:勇敢踏上这第一步
    有关嵌入式linux的注意点总结
    《nodejs开发指南》微博实例express4.x版
    JavaScript中的数据类型转换
  • 原文地址:https://www.cnblogs.com/phpnan/p/phpnan.html
Copyright © 2020-2023  润新知