,golang的协程相信大家都不陌生,在golang中的使用也很简单,只要加上一个关键字「go」即可,虽然说大家都知道,但是真的在实际使用中又遇到这样那样的问题,坑其实还是挺多的。而网上很多文章和教程,要么就是讲的太简单,给你简单介绍一下协程和管道的使用,「点到为止」,要么就上来给你写GPM模型,看的人「一脸懵逼」,所以我以「实际使用过程中遇到的问题」这个角度出发,可能会分多篇总结一下golang的协程相关的知识点,希望对你有用。,ps:如果你从来没有了解过golang的协程,建议先自己搜一些资料简单的了解一下,还有并发并行那些基础概念之类的,本文都不会提及。,我们先看下列程序:,如果有并发问题,我们最容易想到的一个办法就是加锁。,上面过程我画了一张图,具体哪里为什么加锁都有说明。,
,上述程序执行过程图示,channel本质就是一个「数据结构,队列」。既然是队列,当然有着「先进先出」的原则,而且是能保证「线程安全」的,多个gorountine访问不需要加锁。,当然如果你还没有接触过管道,可以提前找些资料了解一下,下面是一个管道的简单示意图。,
,管道(channel)在使用的过程中有很多需要注意的点,我在这里列一下。,为什么需要make,前面文章已经讲过,可以看看,聊聊golang的make和new函数指定长度也很好理解,「管道的本质是队列」,队列当然是需要指定长度的。,上面例子我们可以看到,如果管道定义为interface类型,任何类型的数据都是可以写入并且正常取出的,但是我们写入「结构体类型」之后,如果想取出结构体的「具体属性」,则需要断言。,这个很好理解,我就不用代码演示了,因为每次从管道中取一个数据,len(chan)是变化的,所以这么取数据肯定是有问题的。换句话说也就是「不要随便用len(chan),坑很多」。,我们前面抛出的问题是,「开启协程操作map会引发并发问题」,现在我们看看怎么用管道解决他。,
,协程和管道配合解决map写入并发问题,咱们用协程的目的就是想提高程序的运行效率,管道可以简单理解为是协助协程一起使用的,但是效率到底能提升多少呢?咱们一起来看一看。,大家都知道,判断素数的复杂度是N²,比较慢,咱们先看一看传统的一个一个的去判断需要多长时间,接下来我们用协程和管道的方式看看,还是老规矩,我们先看看流程图。,
,协程和管道配合查找素数,上述程序执行时间为「848.455084ms」,是传统的方式的时间的「四分之一」,可见协程在提高运行效率这块的作用还是显而易见的。
© 版权声明
文章版权归作者所有,未经允许请勿转载。