Go语言学习教程(十六)

一、死锁

* 在主goroutine中向无缓存channel添加内容或在主goroutine中向channel添加内容且添加内容的个数已经大于channel缓存个数就会产生死锁

    fatal error : all goroutines are asleep -deadlock!

* 死锁:在程序中多个进程(Golang中goroutine)由于相互竞争资源而产生的阻塞(等待)状态,而这种状态一直保持下去,此时称这个线程是死锁状态

* 在Golang中使用无缓存channel时一定要注意.以下是一个最简单的死锁程序

    * 主协程中有ch<-1,无缓存channel无论添加还是取出数据都会阻塞goroutine,当前程序无其他代码,主goroutine会一直被阻塞下去,此时主goroutine就是死锁状态

    func main() {

       ch := make(chan int)

       ch <- 1

    }

* 而下面代码就不会产生死锁

    * 通过代码示例可以看出,在使用无缓存channel时,特别要注意的是在主协程中要操作channel代码

    func main() {

       ch := make(chan int)

       go func() {

          ch <- 1

          fmt.Println("执行goroutine")

       }()

       time.Sleep(5e9)

       fmt.Println("程序执行结束")

    }

二、有缓存通道

* 创建一个有缓存通道

func main() {

   ch := make(chan int, 3) //缓存大小3,里面消息个数小于等于3时都不会阻塞goroutine

   ch <- 1

   ch <- 2

   ch <- 3

   ch <- 4 //此行出现死锁,超过缓存大小数量

}

* 在Golang中有缓存channel的缓存大小是不能改变的,但是只要不超过缓存数量大小,都不会出现阻塞状态

    func main() {

       ch := make(chan int, 3) //缓存大小3,里面消息个数小于等于3时都不会阻塞goroutine

       ch <- 1

       fmt.Println(<-ch)

       ch <- 2

       fmt.Println(<-ch)

       ch <- 3

       ch <- 4

       fmt.Println(len(ch))//输出2,表示channel中有两个消息

       fmt.Println(cap(ch))//输出3,表示缓存大小总量为3

    }

三、select简介

* Golang中select和switch结构特别像,但是select中case的条件只能是I/O

* select 的语法(condition是条件)

    select{

      case condition:

      case condition:

      default:

    }

* select执行过程:

    * 每个case必须是一个IO操作

    * 哪个case可以执行就执行哪个

    * 多个case都可以执行,随机执行一个

    * 所有case都不能执行时,执行default

    * 所有case都不能执行,且没有default,将会阻塞

func main() {

   runtime.GOMAXPROCS(1)

   ch1 := make(chan int, 1)

   ch2 := make(chan string, 1)

   ch1 <- 1

   ch2 <- "hello"

   select {

   case value := <-ch1:

      fmt.Println(value)

   case value := <-ch2:

      fmt.Println(value)

   }

}

* select多和for循环结合使用,下面演示出了一直在接收消息的例子

func main() {

    ch := make(chan int)

    for i := 1; i <= 5; i++ {

        go func(arg int) {

            ch <- arg

        }(i)

    }

  //如果是一直接受消息,应该是死循环for{},下面代码中是明确知道消息个数

    for i := 1; i <= 5; i++ {

        select {

        case c := <-ch:

            fmt.Println("取出数据", c)

        default:

            //没有default会出现死锁

        }

    }

    fmt.Println("程序执行结束")

}

* break可以对select生效,如果for中嵌套select,break选择最近结构

四、GC

* GC英文全称 garbage collector

* Go语言GC是相对C/C++语言非常重要的改进

* 一些常用GC算法

    * 引用计算法:当对象被引用时计算器加一.不被引用计数器减一

        * PHP和Object-C使用

        * 相互引用无法回收

        * 计数增加消耗

    * Mark And Sweep 标记和清除算法:停止程序运行,递归遍历对象,进行标记。标记完成后将所有没有引用的对象进行清除

        * 由于标记需要停止程序(Stop the world),当对象特别多时,标记和清除过程比较耗时(可能几百毫秒),很难接受

    * 三色标记法:是Mark And Sweep的改进版.从逻辑上分为白色区(未搜索),灰色区(正搜索),黑色区(已搜索).灰色区内容是子引用没有进行搜索,黑色区表示子引用存在

    * 分代收集:一般情况都有三代,例如java中新生代,老年代,永久代.当新生代中带有阈值时会把对象放入到老年代,相同道理老年代内容达到阈值会放入到永久代

五、Go语言中的GC

* Go语言中采用Stop The World方式

* Golang每个版本基本上都会对GC进行优化,从Golang1.5开始支持并发(concurrent )收集,从1.8版本已经把STW时间优化到了100微妙,通常只需要10微秒以下.且在1.10版本时再次优化减少GC对CPU占用

* Go语言中GC是自动运行的,在下列情况下会触发GC

    * 当需要申请内存时,发现GC是上次GC两倍时会触发

    * 每2分钟自动运行一次GC

* GC调优

    * 小对象复用,局部变量尽量少声明,多个小对象可以放入到结构体,方便GC扫描

    * 少用string的”+”

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,053评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,527评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,779评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,685评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,699评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,609评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,989评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,654评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,890评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,634评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,716评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,394评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,976评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,950评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,191评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,849评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,458评论 2 342

推荐阅读更多精彩内容