管道阻塞的机制|学习笔记

简介: 快速学习管道阻塞的机制

开发者学堂课程【Go 语言核心编程 - 面向对象、文件、单元测试、反射、TCP 编程:管道阻塞的机制】学习笔记,与课程紧密联系,让用户快速学习知识。

课程地址:https://developer.aliyun.com/learning/course/626/detail/9758


管道阻塞的机制

 

内容介绍:

一、goroutine 和 channel 结合

应用实例1

应用实例2-阻塞

 

一、goroutine 和 channel结合

应用实例1

请完成 goroutine 和 channel 协同工作的案例,

具体要求:

1)开启一个 writeData 协程,向管道 intChan 中写入50个整数.

2)开启一个 readData 协程,从管道 intChan 中读取 writeData 写入的数据。

3)注意: writeData 和 readDate 操作的是同一个管道

4)主线程需要等待 writeData 和 readDate 协程都完成工作才能退出【管道】

思路分析示意图如下:

image.png

遇到管道多的情况,要利用画思路图来帮助我们理解和分析,进而解决问题。

代码的实现:

1package main

2import (

3  "fmt"

4  )

5

6

7 //write Data

8  func writeData(intchan chan int) {

9  for i := 1; i <= 50; i++ {

10 //放入数据

11 intchan<- i

12  }

13 }

14

15

16//read data

17 func readData(intchan chan int,exitchan chan bool){

18

19for {

20 v, ok := <-intchan

21 if !ok {

22break

23 }

24 fmt.Printf( "readData读到数据=%v\n", v)

25   }

26 // readData读取完数据后,即任务完成

27 exitchan<- true

28 close(exitchan)}

29

30 //创建两个管道

31 intchan := make( chan int. 50)

32 exitchan := make(chan bool,1)

33 go writeData(intchan)

34 go readData(intchan, exitchan)

35 //time-sleep(time.second*10)

36 for{

37 ok := <-exitchan

38if !ok {

39break

40}

41}

应用实例2-阻塞

func main() {

intchan := make(chan int, 10) l/10->50的话数据一下就放入了

exitChan := make(chan bool,1)

go writeData(intChan)

//go readData(intChan, exitChan)

//就是为了等待..readData 协程完成

for _ = range exitChan {

fmt.Println("ok...")

}

问题:如果注销掉 go readData(intChan,exitChan),程序会怎么样?

分析:注销后,只有写入数据,没有读取数据,如果编译器(运行)发现一个管道只有写入,而没有读取,写入的数据超过其容量,则该管道会阻塞。但如果两个协程同时存在时,写管道和读管道的频率不一致,无所谓。

只有写入的过程,没有读取的过程,写的依次增加,最终会使管道因数据增多而阻塞,管道很小,数据量很大,写入的数据超过超过管道容量,会发生报错。

写的快,读的慢时,不会失锁,因为编译器会进行分析,不会发生阻塞。即管道不停的流动就不会报错和发生错误。

写的速度很快,读取时一秒钟读取一次,显然速度是不同步的,但仍然不会报错。编译器的编译结果如下:(没有发生报错)

image.png

答: 如果只是向管道写入数据,而没有读取,就会出现阻塞而 dead lock,原因是intChan 容量是10,而代码 writeData 会写入50个数据,因此会阻塞在 writeData 的 ch <- i

如果编译器(运行),发现一个管道只有写入的过程,而没有读取的过程,则该管道会发生阻塞。

假设开设50个管道,写入50个数据,但有一个地方没有被读取,就不会发生阻塞。如果发生阻塞,可能是其他原因导致的。

写管道和读管道的频率不一致,不会发生阻塞,是有意义的阻塞,在时间足够的情况下,能够完成相应工作。当发现没有等下去的希望时,就会发生报错。

运行时,编译器底层会有一种分析机制,不断维护着上下文。

注:

注销掉 go readData(intChan,exitChan) 后,编译器的编译结果如下:(发生阻塞deadlock)

image.png

相关文章
|
6月前
|
Java
如何理解网络阻塞 I/O:BIO
如何理解网络阻塞 I/O:BIO
|
6月前
|
负载均衡 NoSQL 网络协议
网络中的阻塞与非阻塞以及reactor模型
网络中的阻塞与非阻塞以及reactor模型
43 0
|
6月前
|
Shell
【进程通信】利用管道创建进程池(结合代码)
【进程通信】利用管道创建进程池(结合代码)
|
6月前
|
负载均衡 Java Linux
管道,信号量,共享内存,socket的实际使用场景和NSPipe管道的使用
管道,信号量,共享内存,socket的实际使用场景和NSPipe管道的使用
87 0
阻塞式/非阻塞式与同步/异步的区别
阻塞式/非阻塞式与同步/异步的区别
87 0
|
网络协议 Java
BIO 同步阻塞模型
BIO 同步阻塞模型
BIO 同步阻塞模型
|
调度 C++
进程、线程、并发、并行、同步、异步、阻塞、非阻塞
乎所有的操作系统都支持同时运行多个任务,一个任务通常就是一个程序,每个运行中的程序就是一个进程。当一个程序运行时,内部可能包含了多个顺序执行流,每个顺序执行流就是一个线程。
|
Java
一文读懂阻塞、非阻塞、同步、异步IO
原文:一文读懂阻塞、非阻塞、同步、异步IO 介绍     在谈及网络IO的时候总避不开阻塞、非阻塞、同步、异步、IO多路复用、select、poll、epoll等这几个词语。在面试的时候也会被经常问到这几个的区别。
5565 0
网络基础 - 同步、异步、阻塞、非阻塞
网络基础 - 同步、异步、阻塞、非阻塞
197 0

相关实验场景

更多
下一篇
无影云桌面