目录

Channel用法

1 Channel

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
func create() chan int{
  c := make(chan int)
  go func(){
    for i:=0;i<100;i++{
      c <- i
    }
    close(c)
  }
  return c
}

2 bufferChannel

1
2
3
4
5
6
7
8
9
// 缓冲chan
func bufferedChannl() {
	c := make(chan int, 3)
	go worker(1,c)
	c <- 1
	c <- 2
	c <- 3
	//c <- 4
}

3 close channel

1
2
3
4
5
6
7
8
9
// 关闭通道只能是数据发送方
func closechannel() {
	c := make(chan int)
	go worker(0, c)
	c <- 1
	c <- 2
	c <- 3
	close(c)
}
  • 方式一:ok,双返回值
1
2
3
4
5
6
7
8
func worker(id int, c chan int) {
	for {
		n, ok := <-c
		if ok {
			fmt.Printf("worker %d received %d\n", id, n)
		}
	}
}
  • 方式二: range
1
2
3
4
5
6
func worker(id int, c chan int) {
	for n := range c{
		fmt.Printf("worker %d received %d\n", id, n)
	}
}

CSP模型

  • 不要用共享内存来通信,应该用通信来共享内存
4.1 channel 作为同步信号量
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
type worker struct {
	in   chan int
	done chan bool // 同步信号量
}

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

}

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


func channelDemo() {
	var workers [10] worker

	for i := range workers {
		workers[i] = createWorker(0,workers[i])
	}

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

output

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
worker 0 received a
worker 0 received b
worker 0 received c
worker 0 received d
worker 0 received e
worker 0 received f
worker 0 received g
worker 0 received h
worker 0 received i
worker 0 received j
4.2 并发执行
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
func doWork(id int, w worker) {
	for n := range w.in {
		fmt.Printf("worker %d received %c\n", id, n)
		go func() {
			w.done <- true
		}()
    
	}
}

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

func channelDemo() {
	var workers [10] worker

	for i := range workers {
		workers[i] = createWorker(0, workers[i])
	}

	for i, w := range workers {
		w.in <- 'a' + i
	}

	for i, w := range workers {
		w.in <- 'A' + i
	}

	for _, w := range workers {
		<-w.done
	}

}

func main() {
	channelDemo()
}

4.3 生产者消费者模型
  • Select
  • Time channel 指定时间后向通道写入内容,达到阻塞程序执行的目的
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
//
func generator() chan int {
	out := make(chan int)
	go func() {
		i := 0
		for {
			out <- i
			time.Sleep(time.Duration(rand.Intn(1500)) * time.Millisecond)
			i++
		}
	}()
	return out
}

// 从管道中取数据 然后打印数据
func doWork(i int, c chan int) {
	for cc := range c {
		time.Sleep(3000 * time.Millisecond)
		fmt.Println(cc)
	}

}

func createWorker(i int) chan int {
	c := make(chan int)
	go doWork(i, c)
	return c
}

func main() {

	tick := time.After(10 * time.Second)

	tick2 := time.Tick(time.Second)

	A, B := generator(), generator()
	w := createWorker(0)
	n := 0
	var values [] int
	//hasvalue := false
	for {
		var activeWorker chan int
		//
		//if hasvalue{
		//	activeWorker = w
		//}
		var activeValue int

		if len(values) > 0 {
			activeValue = values[0]
			activeWorker = w
		}

		select {
		case n = <-A:
			//fmt.Printf("receied %d from A\n", n)
			//w <- n
			//hasvalue = true
			values = append(values, n)
		case n = <-B:
			//fmt.Printf("receied %d from B\n", n)
			//w <- n
			//hasvalue = true
			values = append(values, n)
		case activeWorker <- activeValue:
			//hasvalue = false
			values = values[1:]

		case <- tick:
			fmt.Println("bye")
			return

		case <- tick2:
			fmt.Printf("队列中积压的数据%d\n", len(values))
		}
	}
}