go并发相关学习01
1.基础
- c语言并发最小单位是线程,即多线程。
- go语言中不是线程,而是go程->goroutine。
- 一个go程占用的系统资源远远小于线程,默认大约需要4k-5k的内存资源。
- 使用go程,只要在目标函数前加上go关键字即可。
1 | package main |
1 | go程: 1 |
2.提前退出
1 | package main |
3.管道
1 | package main |
有缓存通道输出(日志输出存在竞争)
1 | 是主go程,写入数据: 0 |
无缓存通道输出(日志输出存在竞争)
1 | 这是子go程1, data: 0 |
写 > 读+缓存空间 程序阻塞在写入的位置。
读>写 程序阻塞在读取的位置。
主go程出现读或写阻塞会出现崩溃,错误原因deadlock
子go程出现读写阻塞会一直卡住,不会崩,可以利用这一点,但是如果逻辑错误导致永久死锁时,会有内存泄漏。
4.for-range遍历管道
1 | package main |
1 | 这是子go程2,写入数据: 100 |
5.管道总结
- 当管道写满了,写阻塞。
- 当缓冲区读完了,读阻塞。
- 如果管道没有使用make分配空间,管道默认是nil,从nil管道读取数据,写入数据,都会阻塞,但是不会崩溃
- 从一个已经close的管道可以正常读取未消费的数据,当没有数据可读时,会返回零值
- 向一个已经close的管道写入数据时,会崩溃
- 关闭一个已经close的管道,会崩溃
- 关闭管道的动作一定要做在写端执行,不应该放在读端,否则写段继续写会崩溃
- 读写的次数,一般需要对等,否则:
- 在多个go程中:资源泄漏
- 在主go程中,程序崩溃(deadlock)
6.判断管道状态
1 | package main |
1 | write data: 0 |
7.单向通道
1 | numChan := make(chan int, 10) //双向通道,即可读也可写 |
单向通道:为了明确语义,一般用于函数参数
- 单向读:var numChanReadOnly <- chan int
- 单向写:var numChanWriteOnly chan <- int
1 | package main |
1 | write data: 0 |
8.select
当程序中有多个channel协同工作时,select监听多个通道,管道被触发时(写入,读取,关闭),可以进行对应处理,select的使用和switch类似,但是select的对象是io。
1 | package main |
1 | elect... |