使用channel等待任务结束

加一个chan通知发送方

package main

import "fmt"

func main() {
	chanDemo()
}

func chanDemo() {
	var workers [10]worker
	for i := 0; i < 10; i++ {
		workers[i] = createWorker(i)
	}
	for i := range workers {
		workers[i].in <- 'a' + i
		<-workers[i].done
	}
	for i := range workers {
		workers[i].in <- 'A' + i
		<-workers[i].done
	}
}

type worker struct {
	in   chan int
	done chan bool
}

func createWorker(id int) worker {
	w := worker{
		in:   make(chan int),
		done: make(chan bool),
	}
	go doWork(id, w.in, w.done)
	return w
}

func doWork(id int, in chan int, done chan bool) {
	for n := range in {
		fmt.Printf("Worker %d received %c\n", id, n)
		done <- true
	}
}

在这里插入图片描述
这个虽然做到了通知,但是每个任务都是顺序执行的,失去了并行意义!

统一等待所有任务结束

package main

import "fmt"

func main() {
	chanDemo()
}

func chanDemo() {
	var workers [10]worker
	for i := 0; i < 10; i++ {
		workers[i] = createWorker(i)
	}
	for i := range workers {
		workers[i].in <- 'a' + i

	}
	for i := range workers {
		workers[i].in <- 'A' + i

	}
	for i := range workers {
		<-workers[i].done
		<-workers[i].done
	}
}

type worker struct {
	in   chan int
	done chan bool
}

func createWorker(id int) worker {
	w := worker{
		in:   make(chan int),
		done: make(chan bool),
	}
	go doWork(id, w.in, w.done)
	return w
}

func doWork(id int, in chan int, done chan bool) {
	for n := range in {
		fmt.Printf("Worker %d received %c\n", id, n)
		done <- true
	}
}

在这里插入图片描述
第一组小写的全部执行完毕,等到第二组执行时出现deadlock;所有的chan发送都是阻塞式的,有发送方就必须得有接收方;第一组发送的true等待外面去接收;第二组又开始发送,开始了循环等待,出现deadlock

并行通知

package main

import "fmt"

func main() {
	chanDemo()
}

func chanDemo() {
	var workers [10]worker
	for i := 0; i < 10; i++ {
		workers[i] = createWorker(i)
	}
	for i := range workers {
		workers[i].in <- 'a' + i

	}
	for i := range workers {
		workers[i].in <- 'A' + i

	}
	for i := range workers {
		<-workers[i].done
		<-workers[i].done
	}
}

type worker struct {
	in   chan int
	done chan bool
}

func createWorker(id int) worker {
	w := worker{
		in:   make(chan int),
		done: make(chan bool),
	}
	go doWork(id, w.in, w.done)
	return w
}

func doWork(id int, in chan int, done chan bool) {
	for n := range in {
		fmt.Printf("Worker %d received %c\n", id, n)
		go func() { done <- true }()
	}
}

在这里插入图片描述

WaitGroup

package main

import (
	"fmt"
	"sync"
)

func main() {
	chanDemo()
}

func chanDemo() {
	var workers [10]worker
	var wg sync.WaitGroup
	wg.Add(len(workers) * 2)
	for i := 0; i < 10; i++ {
		workers[i] = createWorker(i, &wg)
	}
	for i := range workers {
		workers[i].in <- 'a' + i

	}
	for i := range workers {
		workers[i].in <- 'A' + i

	}
	wg.Wait()
}

type worker struct {
	in chan int
	wg *sync.WaitGroup
}

func createWorker(id int, wg *sync.WaitGroup) worker {
	w := worker{
		in: make(chan int),
		wg: wg,
	}
	go doWork(id, w.in, wg)
	return w
}

func doWork(id int, in chan int, wg *sync.WaitGroup) {
	for n := range in {
		fmt.Printf("Worker %d received %c\n", id, n)
		wg.Done()
	}
}

在这里插入图片描述

package main

import (
	"fmt"
	"sync"
)

func main() {
	chanDemo()
}

func chanDemo() {
	var workers [10]worker
	var wg sync.WaitGroup
	wg.Add(len(workers) * 2)
	for i := 0; i < 10; i++ {
		workers[i] = createWorker(i, &wg)
	}
	for i := range workers {
		workers[i].in <- 'a' + i

	}
	for i := range workers {
		workers[i].in <- 'A' + i

	}
	wg.Wait()
}

type worker struct {
	in chan int
	done func()
}

func createWorker(id int, wg *sync.WaitGroup) worker {
	w := worker{
		in: make(chan int),
		done: func() {
			wg.Done()
		},
	}
	go doWork(id, w)
	return w
}

func doWork(id int, w worker) {
	for n := range w.in {
		fmt.Printf("Worker %d received %c\n", id, n)
		w.done()
	}
}

在这里插入图片描述

使用channel求出树的最大节点

package main

import (
	"fmt"
	"math"
)

type Node struct {
	Value       int
	Left, Right *Node
}

func CreateNode(value int) *Node {
	return &Node{Value: value}
}

func (node Node) Print() {
	fmt.Print(node.Value, " ")
}

func (node *Node) SetValue(value int) {
	if node == nil {
		fmt.Println("node is nil")
		return
	}
	node.Value = value
}

func (node *Node) Traverse() {
	node.TraverseFunc(func(n *Node) {
		n.Print()
	})
	fmt.Println()
}
func (node *Node) TraverseFunc(f func(node *Node)) {
	if node == nil {
		return
	}
	node.Left.TraverseFunc(f)
	f(node)
	node.Right.TraverseFunc(f)
}

func (node *Node) TraverseWithChannel() chan *Node {
	c := make(chan *Node)
	go func() {
		node.TraverseFunc(func(node *Node) {
			c <- node
		})
		close(c)
	}()
	return c
}

func main() {
	root := Node{Value: 3}
	root.Left = &Node{Value: 1}
	root.Right = &Node{5, nil, nil}
	root.Right.Left = new(Node)
	root.Left.Right = CreateNode(2)
	root.Right.Left.SetValue(4)

	// 1 2 3 4 5
	root.Traverse()

	count := 0
	root.TraverseFunc(func(node *Node) {
		count++
	})
	// 5
	fmt.Println(count)

	c := root.TraverseWithChannel()
	maxNode := math.MinInt64
	for node := range c{
		if node.Value > maxNode {
			maxNode = node.Value
		}
	}
	fmt.Println(maxNode)
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

.番茄炒蛋

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值