table of Contents
Precautions
- goroutine only official super thread pool
- High concurrency: small memory, quickly create destruction
- Giving developers a huge convenience easy to use, but also the language level of goroutine
- Complicated than in parallel, the parallel operation is directly implemented multicore multithreaded, concurrency is achieved by the switching time slice "simultaneous" operation
goroutine pursue shared by communication (channel) memory instead of shared memory for communication
channel
- goroutine channel is a bridge, mostly blocking synchronous
- Created by make, close Close
channel is a reference type, that is, parameters can be passed directly to his own operation
func main(){
c := make(chan bool)
go func(){
fmt.Println("GO GO GO")
c <- true
}()
<- c
}
/*
> Output:
command-line-arguments
GO GO GO
*/
- It can be used for range to iterate continuously operating channel
- Iteration time I must remember to call the close somewhere (c) closed , to avoid deadlock
func main(){
c := make(chan bool)
go func(){
fmt.Println("GO GO GO")
c <- true
close(c)
}()
for v := range c {
//程序运行到这,一直等待着c会有值
fmt.Println(v)
}
}
- Unidirectional or bidirectional channel may be provided
You can set the cache size, blocking does not occur before the unfilled
on caching, refer to: Go Language _ concurrent papers
have cache is asynchronous, non-blocking cache is synchronized
has put the first cache
without first taking CacheDisorder and lack of problems ..whatever
func main(){
runtime.GOMAXPROCS(runtime.NumCPU())
c := make(chan bool)
for i:=0; i<10 ; i++ {
go Go(c,i)
}
<-c
}
func Go(c chan bool, index int){
a := 1
for i:=0;i<1000000;i++{
a += i
}
fmt.Println(index,a)
if index==9 {
c <- true
}
}
/*
> Output:
command-line-arguments
1 499999500001
0 499999500001
2 499999500001
9 499999500001
*/
Does not meet the above output is holy, ministers gave the following two plan
A plan: to channel plus buffer
func main(){
runtime.GOMAXPROCS(runtime.NumCPU())
c := make(chan bool,10)
for i:=0; i<10; i++ {
go Go(c,i)
}
for i:=0;i<10;i++{
<- c
}
}
func Go(c chan bool, index int){
a := 1
for i:=0;i<1000000;i++{
a += i
}
fmt.Println(index,a)
c <- true
}
/*
> Output:
command-line-arguments
2 499999500001
1 499999500001
9 499999500001
0 499999500001
6 499999500001
3 499999500001
5 499999500001
7 499999500001
8 499999500001
4 499999500001
*/
Trick two: introducing sync packet
package main
import (
"fmt"
"runtime"
"sync"
)
func main(){
//(runtime包是goroutine的调度器),runtime.GOMAXPROCE设置允许同时最多使用多少个核
runtime.GOMAXPROCS(runtime.NumCPU())
wg := sync.WaitGroup{}
for i:=0; i<10; i++ {
//waitgroup作为结构,使用&进行地址传递
go Go(&wg,i)
}
wg.Wait()
}
func Go(wg *sync.WaitGroup, index int){
a := 1
for i:=0;i<1000000;i++{
a += i
}
fmt.Println(index,a)
wg.Done()
}
select
- Structure designed specifically to channel
func main(){
c1,c2 := make(chan int),make(chan string)
o := make(chan bool)
go func(){
for{
select{
case v,ok := <-c1:
if !ok{
o <- true
break
}
fmt.Println("c1",v)
case v,ok := <-c2:
if !ok{
o <- true
break
}
fmt.Println("c2",v)
}
}
}()
c1 <- 1
c2 <- "hi"
c1 <- 3
c2 <- "lel"
close(c1)
//close(c2)
for i:=0;i<2;i++{
<- o
}
}
//没办法同时记录两个select的执行次数
- You may process the one or more channel transmission and reception
func main(){
c := make(chan int)
go func(){
i := 0
for v:= range c {
i ++
fmt.Println(v)
if i>10{
break
}
}
}()
for {
select {
case c <- 0:
case c <- 1:
}
}
}
//运行结果很鬼畜,,
- Random order channel simultaneously with a plurality of available processing
- Available empty select to block the main function
- You can set the timeout
package main
import (
"fmt"
"time"
)
func main(){
c := make(chan bool)
select {
case v := <- c:
fmt.Println(v)
case <-time.After(3*time.Second):
fmt.Println("timeout")
}
}
//time.After()返回一个time型的chan
Examples: the number of message transmission and reception achieved by goroutine
package main
import (
"fmt"
)
var cc chan string
func main() {
cc = make(chan string)
go Go()
for i := 0; i < 5; i++ {
cc <- fmt.Sprintf("From main:hello, #%d", i)
fmt.Println(<-cc)
}
}
func Go() {
for i := 0; ; i++ {
fmt.Println("djd", <-cc)
cc <- fmt.Sprintf("From Go:hi,#%d", i)
}
}
/*
djd From main:hello, #0
From Go:hi,#0
djd From main:hello, #1
From Go:hi,#1
djd From main:hello, #2
From Go:hi,#2
djd From main:hello, #3
From Go:hi,#3
djd From main:hello, #4
From Go:hi,#4
*/