并发程序之间的数据传递:
其他语言:
通过共享内存实现消息传递。
go语言:
通过数据传递来实现共享内存。
队列结构:
队列queue:
是一种数据结构—-FIFO(先进先出)
数据结构:数据存储的特点。
数组、切片————线性结构。
栈stack—LIFO(后进先出)
channel:
01、通道概念:
专门的goroutines通信的管道。类似于管道中的水从一端到另一端的流动,数据可以从一端发送到另一端,通过通道接收。
02、通道目的:
实现多个goroutine之间实现数据传递。
03、通道的本质:
通道是一种容器,通道是一种数据结构—队列结构
容器,相当于”消息队列”。
04、通道的语法:
make()创建,也是引用类型的数据。
需要关联一种相关的数据类型。
05、通道的操作:
一个goroutine可以从chan中读取数据,另一个goroutine可以从中写入数据。
不能一个goroutine又读又写,会产生阻塞。
从chan中读取数据:
<- 特殊操作符
从chan中读取数据,data := <-chan 从chan中读取数据
向chan中写入数据,chan<-data 将data的数据写入chan
nil chan,同map一样不能使用,需要make()创建
06、通道阻塞:
对于chan的读取和写入操作,都是阻塞式的。
阻塞式:导致程序暂时不能执行! 直到解除阻塞!!
* 从chan中读取数据:阻塞式,直到另一个goroutine向通道中写入数据,才能解除阻塞。
* 向chan中写入数据:阻塞式,直到另一个goroutine向通道中读取出数据,才能解除阻塞。
07、通道安全:
通道本身是安全的。同一时间,只能允许一个goroutine来读或写。
01、通道声明:简单实用通道
1 | package main |
02、通道阻塞:
1 | package main |
03、通道关闭:
读取通道:data:=<-chan
data,ok:=<-chan
ok为true,表示通道正常,读取到的data数据有效可用。
ok为false,表示通道关闭,读取到的data是类型的零值(默认值)。
与value,ok:=map[key]类似
通道关闭:
发送方如果数据写入完毕,可以关闭通道,用于通知接收方没有数据了,数据传输完毕。
一般只有发送方关闭。
g1—>写入数据
g2—>读取数据
发送方,不停的写入数据
循环发送,循环结束,发送停止写入
最后需要关闭通道,用于通知接收方没有数据了
接收方,不停的读取数据
死循环,读取数据,根据ok的值判断,是否已经结束。
1 | //01、接收方----for循环接收数据,需要判断关闭通道了,跳出死循环 |
** 03.1、通过data,ok:=<-chan中的ok来判断是否跳出死循环**
1 | package main |
** 03.2、通过for-range,发送方关闭通道,才能跳出死循环的方式读取数据。**
1 | package main |
04、缓冲通道
1 | package main |
05、生产者和消费者:
生产者/消费者模型: ——线程之间的通信
生产者:生产产品
消费者:消费产品
比如:
母鸡:生产者 ——-线程t1 生产 notify()唤醒和notifyAll()唤醒所有
产品:鸡蛋
吃货:消费者 ——-线程t2 需要使用wait()进行阻塞,取数据 wait()等待;一般不用sleep()
notify()唤醒母鸡
商店:存储一定容量的鸡蛋 ——–容器 通道, 队列
一个生产者,两个消费者。
1 | package main |
06、定向通道:
通道:
默认是双向通道。
可读可写
能存能取。
make(chan Type)
定向通道:
也叫单向通道,只读或只写
只读
make(<-chan Type)
只能读取数据
只写
** make(chan<- Type)**
只能写入数据
创建通道时,采用单向通道,没有意义!
传递参数的时候使用:
函数,只有写入数据。
函数,只有读取数据。
语法级别保证通道的操作安全。
1 | package main |
07、计时器: time包对chan的操作
** 1.Timer(): 计时器**
- **timer1 := time.NewTimer( duration ) // ***time.Timer 类型
- *Timer对象 中的属性C为: <-chan time.Time
** 2.After(duration**)
- 返回值为 <-chan time.Time 同属性C
1 | package main |
08、select语句:
select语句类似于switch语句,但是select会随机执行一个可运行的case。
如果没有case可以运行,它将阻塞,直到有case可运行。
select是一种分支语句,专门用于通道读写操作的。
select{
case chan读/写:
分支1
case chan读/写:
分支2
case chan读/写:
分支3
…
default:
}
执行流程:
1.每个case后的通道都会被执行,如果多个都可以执行,那么select会随机执行一个可运行的case。
2.如果没有case可以运行,如果有default执行default。
如果没有default它将阻塞,直到有case可运行。
1 | package main |
09、 select+time 超时操作
1 | package main |
- 本文作者: 梁俊可
- 本文链接: http://ljk3d.com/2021/10/19/goLangNote/goLangBasic/14_GoLang语言入门_基础语法_并发与多线程03_channel通道、生产者和消费者、select语句、超时处理/
- 版权声明: 梁俊可工作室