golang最为人乐道的就是语言级别支持协程,但今天的重点我们不讨论协程,而是管道。
管道的特性:
可读写,管道可读写任意类型的数据
管道的读写是协程安全的
管道的操作是阻塞的,如果当前管道已满则无法写入、管道无数据可读均会导致当前协程阻塞
管道可传输任意数据类型比如,比如int、string、指针、或自定义数据结构
管道三种,具体的声明如下:
可读写管道声明make(chan int)
只读管道声明make(<-chan int)
只写管道声明make(chan<- int)
下面是管道的基本用法
管道基本用法
golang提供了语言级别支持协程的特性,从而可以很方便的写出高性能的服务,协程之间的沟通就该轮到管道上场了。尤其是管道的协程安全特性,可以保证多个协程在写一个管道时数据的安全性。
比如:多个协程同时向一个golang数组里面写入数据,即使数组是非协程安全的,但是通过管道进一步包装可以保证数组的完整性。
首先我们要举一个反面的例子,注意下面是反面教材
多协程同时写数组反面教材
这个例子的输出结果是:
&[0 1 0 1 2 3 4 0 1 2 3 4 0 1 2 3 4]
数一数输出的数组数据个数,不到30个数,所以多协程同时写数组,如果不加锁的话会造成数据错误。
下面我们使用协程的安全特性,进行改造:
借助管道协程安全特性保证数据的正确性
这次输出的数据是:
[0 1 2 3 4 0 1 2 3 4 0 0 0 1 1 1 2 2 2 3 3 3 0 1 2 3 4 4 4 4]
可见这次对的了。
回顾下今天讨论的内容:
管道是协程之间沟通的桥梁
管道具有 线程 安全特性,我们可以借助这个特性在非加锁的情况下保证数据的完整性
感谢大家的阅读,喜欢的朋友可以点击下关注,我们一起学习进步。