go 并发模式笔记

 

pipeline(工厂模式)

流水线,由一道道工序构成,没到工序功过channel 把数据传递给下一道工序

每道工序对应一个函数,函数里有协程和channel

协程将处理的数据放入channel中,整个函数会返回channel以供下一道工序使用


//流水线,由一道道工序构成,没到工序功过channel 把数据传递给下一道工序
//每道工序对应一个函数,函数里有协程和channel
//协程将处理的数据放入channel中,整个函数会返回channel以供下一道工序使用
func main() {
	coms := buy(100)
	phones := build(coms)
	packs := pack(phones)
	for p := range packs {
		fmt.Println(p)
	}
}

//流水线模式Pipeline模式

func buy(n int) <-chan string {
	out := make(chan string)
	go func() {
		defer close(out)
		for i := 0; i < n; i++ {
			out <- fmt.Sprint("配件", i)
		}
	}()
	return out
}

// 工序2组装
func build(in <-chan string) <-chan string {
	out := make(chan string)
	go func() {
		defer close(out)
		for c := range in {
			out <- "组装(" + c + ")"
		}
	}()
	return out
}

// 工序3打包
func pack(in <-chan string) <-chan string {
	out := make(chan string)
	go func() {
		defer close(out)
		for c := range in {
			out <- "打包(" + c + ")"
		}
	}()
	return out
}



扇入/扇出模式

        多对一和一对多的关系,让使用效率更高

        

func main2() {
	coms := buy(100)
	phones1 := build(coms)
	phones2 := build(coms)
	phones3 := build(coms)
	phones := merge(phones1, phones2, phones3)
	packs := pack(phones)
	for p := range packs {
		fmt.Println(p)
	}
}

//流水线模式Pipeline模式

func buy(n int) <-chan string {
	out := make(chan string)
	go func() {
		defer close(out)
		for i := 0; i < n; i++ {
			out <- fmt.Sprint("配件", i)
		}
	}()
	return out
}

// 工序2组装
func build(in <-chan string) <-chan string {
	out := make(chan string)
	go func() {
		defer close(out)
		for c := range in {
			out <- "组装(" + c + ")"
		}
	}()
	return out
}

// 工序3打包
func pack(in <-chan string) <-chan string {
	out := make(chan string)
	go func() {
		defer close(out)
		for c := range in {
			out <- "打包(" + c + ")"
		}
	}()
	return out
}

//流水线,由一道道工序构成,没到工序功过channel 把数据传递给下一道工序
//每道工序对应一个函数,函数里有协程和channel
//协程将处理的数据放入channel中,整个函数会返回channel以供下一道工序使用

//扇出和扇入模式

// 扇入
func merge(ins ...<-chan string) <-chan string {
	//多用户协程做同一件事情
	var wg sync.WaitGroup
	out := make(chan string)
	//定义 把一个channel中的数据发送到out
	p := func(in <-chan string) {
		//对wg计数器进行减1操作。
		defer wg.Done()
		for c := range in {
			out <- c
		}
	}
	//设置计数器
	wg.Add(len(ins))
	//扇入 启动多个goroutine 用于处理channel中的数据
	//执行
	for _, cs := range ins {
		go p(cs)
	}

	//新开一个协程,等待所有的协程协程结束
	//等待所有输入的数据ins处理完,再关闭out
	go func() {
		//阻塞直至 WaitGroup 计数器的值为 0 等待其他协程结束
		wg.Wait()
		close(out)
	}()

	return out
}

futures模式

        实际需求中,大量任务之间是相互独立,没有依赖,所以为了提高性能,这些独立的任务就可以并发执行

func futures() {
	vegetablesCh := washVegetables()
	waterCh := boilWater()

	fmt.Println("ready")
	time.Sleep(2 * time.Second)
	fmt.Println("go")
	vegetables := <-vegetablesCh
	water := <-waterCh
	fmt.Println("ready go:", vegetables, water)
}

func washVegetables() <-chan string {
	vegetables := make(chan string)
	go func() {
		time.Sleep(5 * time.Second)
		vegetables <- "洗好的菜"
	}()
	return vegetables
}

func boilWater() <-chan string {
	water := make(chan string)
	go func() {
		time.Sleep(5 * time.Second)
		water <- "烧开的水"
	}()
	return water
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值