加一个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)
}