Go cibcyrrency

并发concurrency

gorountine

切换时间来实现“同时”运行,在并行则是利用多核实现多线程的运行,通过通信共享内存

1
2
3
4
5
6
7
8
9
func Go(){
fmt.Println("Go go!")
}


func main() {
go Go()
time.Sleep(2 * time.Second)
}

Channel

channel 是 goroutine 沟通的桥梁,大都是阻塞同步的,通过 make 创建,close 关闭,channel 是引用类型,使用 for range 来迭代不断操作 channel ,可设置单向或双向通道,缓存大小,在未被填满之前不会发生阻塞

1
2
3
4
5
6
7
8
func main() {
c := make(chan bool)
go func(){
fmt.Println("123")
c <- true
}()
<- c
}

for range

1
2
3
4
5
6
7
8
9
10
11
func main() {
c := make(chan bool)
go func() {
fmt.Println("123")
c <- true
close(c)
}()
for v := range c {
fmt.Println(v)
}
}

缓存

1
c := make(chan bool, 1)

有缓存时同步阻塞的,无缓是异步的

多核运行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
func Go(c chan bool, index int) {
a := 1
for i := 0; i < 10000; i++ {
a += i
}
fmt.Println(index, a)
c <- true
}

func main() {

runtime.GOMAXPROCS(runtime.NumCPU())
c := make(chan bool)
for i := 0; i < 10; i++ {
go Go(c, i)
}
for i := 0 ; i < 10 ; i++ {
<- c
}
}

同步 sync.WaitGroup

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
func Go(wg *sync.WaitGroup, index int) {
a := 1
for i := 0; i < 10000; i++ {
a += i
}
fmt.Println(index, a)
wg.Done()
}

func main() {

runtime.GOMAXPROCS(runtime.NumCPU())
wg := sync.WaitGroup{}
wg.Add(10)
for i := 0; i < 10; i++ {
go Go(&wg, i)
}
wg.Wait()
}

Select

可处理一个或多个 channel 的发生与接收,同时有多个可用的 channel 时按随机顺序处理,可用空的select来阻塞 main 函数,可设置超时

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
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 <- "hello"

close(c1)
close(c2)
}

互相发送

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
func Pingpong() {
i := 0
for {
fmt.Println(<-c)
c <- fmt.Sprintf("From Pingpong: Hi, #%d", i)
i++
}
}

func main() {
c = make(chan string)
go Pingpong()
for i := 0; i < 10; i++ {
c <- fmt.Sprintf("From main: Hello, #%d", i)
fmt.Println(<-c)
}
}
- the End -
0%