-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathChannels.go
154 lines (132 loc) · 2.98 KB
/
Channels.go
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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
// Channels
package main
import (
"fmt"
"time"
)
func channels_() {
messages := make(chan string)
go func() {
messages <- "ping"
}()
msg := <-messages
fmt.Println(msg)
}
func channels_buffering() {
messages := make(chan string, 2)
messages <- "buffered"
messages <- "channel"
fmt.Println(<-messages)
fmt.Println(<-messages)
}
func worker(done chan bool) {
fmt.Print("working ...")
time.Sleep(time.Second)
fmt.Println("done.")
done <- true
}
func channel_synchronization() {
done := make(chan bool, 1)
go worker(done)
<-done
}
func ping(pings chan<- string, msg string) {
pings <- msg
}
func pong(pings <-chan string, pongs chan<- string) {
msg := <-pings
pongs <- msg
}
func channel_directions() {
pings := make(chan string, 1)
pongs := make(chan string, 1)
ping(pings, "passed message.")
pong(pings, pongs)
fmt.Println(<-pongs)
}
/*
Basic sends and receives on channels are blocking.
However, we can use select with a default clause to
implement non-blocking sends, receives, and
even non-blocking multi-way selects.
*/
func channel_non_blocking() {
messages := make(chan string)
signals := make(chan bool)
select {
case msg := <-messages:
fmt.Println("received message", msg)
default:
fmt.Println("no message received")
}
msg := "hi"
select {
case messages <- msg:
fmt.Println("send message", msg)
default:
fmt.Println("no message sent")
}
select {
case msg := <-messages:
fmt.Println("received message", msg)
case sig := <-signals:
fmt.Println("received signal", sig)
default:
fmt.Println("no activity")
}
}
func channel_close() {
jobs := make(chan int, 5)
done := make(chan bool)
go func() {
for {
//In this special 2-value form of receive,
//the more value will be false if jobs
//has been closed and all values
//in the channel have already been received.
j, more := <-jobs
if more {
fmt.Println("received job", j)
} else {
fmt.Println("received all jobs")
done <- true
return
}
}
}()
for j := 1; j <= 3; j++ {
jobs <- j
fmt.Println("send job", j)
time.Sleep(time.Second * 1)
}
/*
chan关闭以后,还是会无阻塞的收到空数值(0),
所以在<-时需要通过第二个参数判断chan是否关闭.
语法为: value, ok := <-chan,if !ok,chan closed
*/
close(jobs)
fmt.Println("send all jobs")
<-done
}
func channel_range() {
queue := make(chan string, 2)
queue <- "one"
queue <- "two"
close(queue)
/*
This range iterates over each element
as it is received from queue.
Because we closed the channel above,
the iteration terminates after
receiving the 2 elements.
If we did not close it we would block
on a 3rd receive in the loop.
This example also showed that
it is possible to close a non-empty
channel but still have the remaining
values be received.
*/
for elem := range queue {
fmt.Println(elem)
}
}