[学习]goroutine & channel

package main

import(
	"fmt"
	"time"
)

func main(){
	go spinner(100 * time.Millisecond)
	const n = 45
	fibN := fib(n)
	fmt.Printf("\rFibonacci(%d) = %d\n",n,fibN)
}

func spinner(delay time.Duration){
	for{
		for _, r := range `-\|/`{
			fmt.Printf("\r%c", r)
			time.Sleep(delay)
		}
	}
}

func fib(x int)int{
	if x < 2{
		return x
	}
	return fib(x-2) + fib(x - 1)
}

spinner为死循环程序,循环打印-\|/,模拟程序运行

通过go 启动一个线程调用spinner函数

然后计算fib,输出结果,main函数结束,强制终止所有线程。

二.通道

package main

import(
	"fmt"
)

func counter(out chan<- int){
	for x := 0; x < 100; x++{
		out <- x
	}
	close(out)
}

func squarer(out chan<- int, in <-chan int){
	for v := range in{
		out <- v * v
	}
	close(out)
}

func printer(in <-chan int){
	for v := range in{
		fmt.Println(v)
	}
}

func main(){
	naturals := make(chan int)
	squares := make(chan int)

	go counter(naturals)
	go squarer(squares, naturals)
	printer(squares)
}

定义naturals,squares为传输int的管道,counter为不断传输自然数的通道,squarer不断接收naturals通道的输入,再将平方输出到squares通道,printer则打印squares通道中的数。counter,squarer通过gorountine线程调用,printer在主线程中调用,直到printer结束。

在 Go 语言中,从一个无缓冲通道中读取数据时,如果没有数据可用,读取操作会被阻塞,直到有数据可用为止。同样地,向一个无缓冲通道中写入数据时,如果通道已满,写入操作也会被阻塞,直到有空间可用为止。

所以squarer会阻塞等待counter输入,printer会阻塞等待squarer输入。

三、使用select多路复用

package main

import(
	"fmt"
	"os"
	"time"
)

func main(){
	abort := make(chan struct{})
	go func(){
		os.Stdin.Read(make([]byte, 1))
		abort <- struct{}{}
	}()
	fmt.Println("commencing countdown. Press return to abort")
	tick := time.Tick(1*time.Second)
	for countdown := 10; countdown > 0; countdown--{
		fmt.Println(countdown)
		select{
		case <- tick:
		case <- abort:
			fmt.Println("launch aborted")
			return
		}
	}
	launch()
}

func launch(){
	fmt.Println("lift off")
}
  1. time.Tick函数返回一个通道,定期发送一个事件
  2. 定义abort通道,标记其它线程触发事件,通过abort中断函数
  3. go func()调用线程获取命令行输入,若有输入,则触发abort通道
  4. 使用select进行多路复用,因为通道在操作完成前都会被阻塞,所以需要使用select
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值