go并发
go并发
go语言天生支持并发!!!
通过goroutine关键字来开启!
goroutine轻量级线程,goroutine运行时管理!!!
同一个程序中的goroutine共享同一个地址空间!!!
语法格式:
go 函数名(参数列表)
示例:
package mian import ( "fmt" "time" ) func sayhello(s string) { for i :=0;i<10;i++{ time.Sleep(100*time.Microsecond) fmt.Println(s) } } func main() { go sayhello("hello") sayhello("world") }
通道(channel)
channel:用来传递数据的一个数据结构!
两个goroutine之间通过传递一个指定的类型值来进行同步和通讯!!!
操作符: <-
ch <- v // 把 v 发送到通道 ch v := <-ch // 从 ch 接收数据 // 并把值赋给 v
申明一个通道:
ch :=make(chan int)
package main import "fmt" func sum(s []int,c chan int){ sum :=0 for _,v := range s{ fmt.Println(v) sum += v } c <- sum } func main() { s := []int{7,2,8,-9,4,0} c := make(chan int) go sum(s[:len(s)/2],c) go sum(s[:len(s)/2],c) x,y := <-c,<-c fmt.Println(x,y,x+y) }
通道缓冲区
设置通道缓冲区的大小,为可选参数
ch :=make(chan int,2)
func main() { ch := make(chan int, 2) ch <- 200000000 ch <- 3000000000000 fmt.Println(<-ch) fmt.Println(<-ch) }
遍历通道和关闭通道
支持range关键字遍历和读取,类似于 切片和数组!!!
遵循先进先出!!!
当通道接收不了数据后,就可以是有close()函数来关闭!!!
使用cap()查看通道的大小!!!
func main() { ch := make(chan int, 10) for i := 0;i<cap(ch);i++{ ch <- i } close(ch) for i := range ch{ fmt.Println(i) } }
延伸
在goroutine的时候主函数先退出,利用chan实现等待goroutine结束后,再退出主函数!!!
闭通道并不会丢失里面的数据,只是让读取通道数据的时候不会读完之后一直阻塞等待新数据写入!!!
有没有缓冲区的区别:
不带缓冲区的通道在向通道发送值时,必须及时接收,且必须一次接收完成。
而带缓冲区的通道则会以缓冲区满而阻塞,直到先塞发送到通道的值被从通道中接收才可以继续往通道传值。就像往水管里推小钢珠一样,如果钢珠塞满没有从另一头放出,那么这一头就没法再往里塞,是一个道理。

浙公网安备 33010602011771号