go语言区块链开发之并发 https://blockchainb.github.io/

1、什么是 channel(管道/通道)?

在 golang 中,channel 是多个 goroutine (线程) 之间传递和同步数据的一种手段。同一时刻,仅有一个线程可以向 channel 发送数据,同样的,同一时刻也只能有一个线程能从 channel 读取数据。

channel 的特性使得它可以解决并发编程可能造成的死锁问题,可以作为Mutex(上锁)及sync多线程编程的替代方案,可以简化代码结构。

2、channel 的声明方式

1varc chanint// var 关键字声明,缓冲int类型数据  

2 varc chanstring// 缓冲string类型数据 

3 c := make(chanint)//  make关键字声明,非缓冲管道

4  c := make(chanint,10)// 缓冲管道 

5  type ChanInt chanint// 设置别名 

总结为:

通过chan关键字标识为管道

有两种声明方式

make方式可以生成缓冲管道非缓冲管道

3、缓冲 channel 和无缓冲 channel 区别?

1 channel1 := make(chanint)// 无缓冲  

2 channel2 := make(chanint,2)// 有缓冲

3  len(channel1)// 长度  

4 cap(channel2)// 容量

无缓冲:

缓冲为1,最多只能缓冲1个数据。无缓冲的读写实际为同步操作,只有当写与读操作匹配时,才会继续,否则会死锁!所以不能同时将读写置于主线程,如果主线程中有读/写操作,必须置于分线程的声明后,

非缓冲的读和写操作必须“相遇”才能执行,否则会阻塞。

就是一个送信人去你家门口送信,你不在家他不走,你一定要接下信,他才会走

有缓冲:

最大缓冲等于容量,相当于一个先进先出的队列。有缓冲的管道,只有当管道容量已存满,在未取走值的情况下继续放值时才会发生阻塞。

4、巧用 channel

通过channel的某些奇技淫巧,可以替代sync,简化代码量,如下示例:

1、 在一个非缓冲管道中,依次循环存入值,并逐个取出

sync实现方法:

package main

import(“fmt””sync”)

var wg sync.WaitGroup //队列

func   main(){

// 先创建一个非缓冲管道

c := make(chanint)    

wg.Add(2)

gofunc(){

//子线程

for       i :=0; i <10; i++ {        

    c <- i//写入数据fmt.Println(“写入数据”)        }      

  wg.Done()    

}()

go     func (){  

fori :=0; i <10; i++ {      

      a := <-c         

   fmt.Println(a) 

//读取数据fmt.Println(“读取数据”)        }     

   wg.Done() 

   }()   

 wg.Wait()}

blockchainb.github.io

    原文作者:BB区块链开发
    原文地址: https://www.jianshu.com/p/d8318c0564d9
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞