go基本语法学习笔记之并发编程

GO并发 在一个函数调用前加上go关键字,这次调用就会在一个新的goroutine中并发执行。
【go基本语法学习笔记之并发编程】

func Add(x, y int) { z := x + y fmt.Println(z) } func main() { for i := 0; i < 10; i++ { go Add(i, i) } }




Go程序从初始化main package并执行main()函数开始,当main()函数返回时,程序退出.且程序并不等待
其他goroutine(非主goroutine)结束。
并发通信 GO语言既以并发编程作为语言的最核心优势,提供了一种通信模型,即以消息机制而非共享内存作为通信方式。 消息机制认为每个并发单元是自包含的、独立的个体,并且都有自己的变量,但在不同并发单元间这些变量不共享。每个并发单元的输入和输出只有一种,那就是消息。 这有点类似于进程的概念,每个进程不会被其他进程打扰,它只做好自己的工作就可以了。不同进程间靠消息来通信,它们不会共享内存。
Go语言提供的消息通信机制被称为channel “不要通过共享内存来通信,而应该通过通信来共享内存。”
channel channel是Go语言在语言级别提供的goroutine间的通信方式。channel是类型相关的
chan声明
var chanName chan ElementType如:
var chint chan int//什么一个int类型的chanvar mchmap[string] chan bool//声明一个map,其元素为boolvar arrch [10]chan int //定义一个


实例

func Count(ch chan int) { ch <- 1 fmt.Println("Counting") } func main() { chs := make([]chan int, 10) for i := 0; i < 10; i++ { chs[i] = make(chan int) go Count(chs[i]) } for _, ch := range(chs) { <-ch } }

定义channel 直接使用内置的函数make()即可:
ch := make(chan int)

channel基本用法 写入
ch < 1

向channel写入数据通常会导致程序阻塞,直到有其他goroutine从这个channel中读取数据

读出
i := < ch

如果ch没有数据也会导致程序阻塞,直到有数据写入ch
但是,对ch的阻塞,可以利用ch的缓冲机制以及select来灵活出来
缓冲机制 带缓冲的channel适合于需连续传输大量数据的场景,定义一个带缓冲的channel,只需将容量传入make的第二个参数即可
c := make(chan int, 1024)//创建了一个大小为1024的整形chan,写入在缓冲区满前 不会阻塞

channel是可传递的
单向channel 单向channel只能用于发送或者接收数据。 声明
var ch1 chan int // ch1是一个正常的channel,不是单向的 var ch2 chan<- float64// ch2是单向channel,只用于写float64数据 var ch3 <-chan int // ch3是单向channel,只用于读取int数据

初始化 channel可以 在单向channel和双向channel之间进行转换,channel本身就是GO的原生类型,因此可被传递,也可类型转换
ch4 := make(chan int) ch5 := <-chan int(ch4) // ch5就是一个单向的读取channel ch6 := chan<- int(ch4) // ch6 是一个单向的写入channel

关闭channel
直接用 close即可
close(ch)

判断channel是否已关闭,可以用多值返回读,如果第二个bool返回值是false则表示ch已经被关闭
x, ok := <-ch

select 用来监控一系列文件句柄发生的IO操作,一旦有其中一个句柄发生IO操作,则被返回 GO在语言级别支持select 代码结构大致如:
select { case <-chan1: // 如果chan1成功读到数据,则进行该case处理语句 case chan2 <- 1: // 如果成功向chan2写入数据,则进行该case处理语句 default: // 如果上面都没有成功,则进入default处理流程 }

其中每个case必须是一个文件句柄操作 结合for可实现循环检测
ch := make(chan int, 1) for { select { case ch <- 0: case ch <- 1: } i := <-ch fmt.Println("Value received:", i) }































    推荐阅读