并发[1][2]

  1. 主体中调用的函数现在是一个 goroutine 并且使用 channel 通讯。不用担心 goroutine 是如何停止的。
import fmt

func shower (c chan int) {
	//等待传值过来
	for {
		i := <- c
		fmt.Println(i)
	}
}

func main () {

	c := make(chan int)

	go shower(c)

	for n := 0; n < 10; n ++ {
		c <- n
	}
}
  1. 更糟的是,由于 main.main() 和 main.shower() 的竞争关系,不是所有数字都被打印了。本应该打印到9, 但是有时只打印到 8。 添加第二个退出 channel, 可以解决这两个问题。
func shower (c chan int, quit chan bool) {
	//等待传值过来
	for {
		select {
		case j := <- c:
			fmt.Println(j)
		//如果是另外一个channel
		case <- quit:
			break

		}
	}
	
}

func main () {

	c := make(chan int)
	quit := make(chan bool)
	go shower(c, quit)

	for n := 0; n < 10; n ++ {
		c <- n
	}
	//for循环结束后往quit channel传递数据
	quit <- false
}
  1. 使用 channel构建斐波那契数列。

package main

import "fmt"

func dup3(in chan int) (chan int, chan int, chan int) {
	//分配
	a, b, c := make(chan int, 2), make(chan int, 2), make(chan int, 2)

	go func() {
		for ; ; {
			t := <-in
			a <- t
			b <- t
			c <- t
		}
	}()

	return a, b, c

}

func fib() chan int {
	x := make(chan int, 2)

	a, b, out := dup3(x)

	go func() {
		x <- 0
		x <- 1
		<-a

		for ; ; {
            //"fib = 0:zipWith (+) fib (1:fib)"
			x <- <-a + <-b
		}
	}()

	return out
}

func main() {
	x := fib()

	for i := 0; i < 20; i ++ {
		fmt.Println(<-x)
	}
}


下一章是通讯ヽ( ̄▽ ̄)و


  1. 题图出处 ↩︎

  2. 书本链接learning go ↩︎