Go的协程和管道

Go有个简单的线程模型,叫做协程。为这个协程配套的简易版“数据同步”叫管道或者信道

在go tour上有两个很有特色的例子:

https://tour.go-zh.org/concurrency/2

package main

import "fmt"

func sum(s []int, c chan int) {
	sum := 0
	for _, v := range s {
		sum += v
	}
	c <- sum // 将和送入 c
}

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 // 从 c 中接收

	fmt.Println(x, y, x+y)
}

这个例子中c信道被两个协程使用,但是对于x,y的赋值却不互相影响。深入的说,就是第一个二分之一切片协程优先把c信道填满了sum,然后另外一个处理后二分之一切片的协程就会自动等待c信道空间,而阻塞在c <- sum行。一直到x<-c,c信道被读出

第二个例子

https://tour.go-zh.org/concurrency/5

package main

import "fmt"

func fibonacci(c, quit chan int) {
	x, y := 0, 1
	for {
		select {
		case c <- x:
			x, y = y, x+y
		case <-quit:
			fmt.Println("quit")
			return
		}
	}
}

func main() {
	c := make(chan int)
	quit := make(chan int)
	go func() {
		for i := 0; i < 10; i++ {
			fmt.Println(<-c)
		}
		quit <- 0
	}()
	fibonacci(c, quit)
}

这个例子中叫死循环fibonacci可以通过select等待多个管道(c和quit)的动作。case c<-x当c信道需要填入的时候,把x填入给他,x的值可以通过case下的程序给出。case <-quit当quit信道有东西要输出的时候,当然也可以写成case q:=<-quit:然后在下面打印quit信道里面的值。

小结:

1.使用go+func就可以简单的实现异步线程

2.当需要在数据层面上做同步的时候,可以使用信道make chan

3.select可以帮助你识别信道的动作,当然这可能和传统思维是相反的,但适应一下就好了

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值