Skip to content

Commit b6f80c9

Browse files
committed
feat(learning):第31条 优先考虑并发设计288
1 parent 44b0e20 commit b6f80c9

11 files changed

+151898
-25
lines changed

chapter4/sources/defer_perf_benchmark_1_test.go

+15-15
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,16 @@ func fooWithoutDefer() {
2020
sum(10)
2121
}
2222

23-
func BenchmarkFooWithDefer(b *testing.B) {
24-
for i := 0; i < b.N; i++ {
25-
fooWithDefer()
26-
}
27-
}
28-
func BenchmarkFooWithoutDefer(b *testing.B) {
29-
for i := 0; i < b.N; i++ {
30-
fooWithoutDefer()
31-
}
32-
}
23+
// func BenchmarkFooWithDefer(b *testing.B) {
24+
// for i := 0; i < b.N; i++ {
25+
// fooWithDefer()
26+
// }
27+
// }
28+
// func BenchmarkFooWithoutDefer(b *testing.B) {
29+
// for i := 0; i < b.N; i++ {
30+
// fooWithoutDefer()
31+
// }
32+
// }
3333

3434
func forLoop() {
3535
for i := 0; i < 100; i++ {
@@ -73,8 +73,8 @@ func BenchmarkFuncWithoutDefer(b *testing.B) {
7373
}
7474
}
7575

76-
func BenchmarkFuncWithPanicRecover(b *testing.B) {
77-
for i := 0; i < b.N; i++ {
78-
FuncWithPanicRecover()
79-
}
80-
}
76+
// func BenchmarkFuncWithPanicRecover(b *testing.B) {
77+
// for i := 0; i < b.N; i++ {
78+
// FuncWithPanicRecover()
79+
// }
80+
// }

chapter4/sources/deferred_func_1.go

+42-1
Original file line numberDiff line numberDiff line change
@@ -143,8 +143,49 @@ func showFileOperation2() {
143143
fmt.Println("write ok")
144144
}
145145

146+
// $GOROOT/src/bytes/buffer.go
147+
func makeSlice(n int) []byte {
148+
// If the make fails, give a known error.
149+
defer func() {
150+
if recover() != nil {
151+
panic(ErrTooLarge)
152+
}
153+
}()
154+
return make([]byte, n)
155+
}
156+
157+
// $GOROOT/src/fmt/scan.go
158+
func (s *ss) Token(skipSpace bool, f func(rune) bool) (tok []byte, err error) {
159+
defer func() {
160+
if e := recover(); e != nil {
161+
if se, ok := e.(scanError); ok {
162+
err = se.err
163+
} else {
164+
panic(e)
165+
}
166+
}
167+
}()
168+
if f == nil {
169+
f = notSpace
170+
}
171+
s.buf = s.buf[:0]
172+
tok = s.token(skipSpace, f)
173+
return
174+
}
175+
176+
var mu sync.Mutex
177+
178+
func BehaveWithDefer() {
179+
fmt.Println("exec BehaveWithDefer")
180+
mu.Lock()
181+
defer mu.Unlock()
182+
bizOp()
183+
}
184+
146185
func main() {
147-
showFileOperation2()
186+
showFileOperation()
187+
// showFileOperation2()
188+
fmt.Println()
148189
}
149190

150191
func copyMap(src map[int]string) map[int]string {

chapter4/sources/foo.txt

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
hello, defer!
2+
hello, defer!

chapter6/sources/concurrency-design-airport-securitycheck-1.go

+52-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
package main
22

3-
import "time"
3+
import (
4+
"fmt"
5+
"time"
6+
)
47

58
const (
69
idCheckTmCost = 60
@@ -38,11 +41,58 @@ func airportSecurityCheck() int {
3841
return total
3942
}
4043

41-
func main() {
44+
func showConcurrency1() {
4245
total := 0
4346
passengers := 30
4447
for i := 0; i < passengers; i++ {
4548
total += airportSecurityCheck()
4649
}
4750
println("total time cost:", total)
4851
}
52+
53+
const (
54+
idCheckTimeout = 60
55+
bodyTimeout = 120
56+
xRayTimeout = 180
57+
)
58+
59+
func idCheck2() int {
60+
time.Sleep(time.Millisecond * time.Duration(idCheckTimeout))
61+
fmt.Println("\tidCheck2 ok")
62+
return idCheckTimeout
63+
}
64+
65+
func bodyCheck2() int {
66+
time.Sleep(time.Millisecond * time.Duration(bodyTimeout))
67+
fmt.Println("\tbodyCheck2 ok")
68+
return bodyTimeout
69+
}
70+
71+
func xRayCheck2() int {
72+
time.Sleep(time.Millisecond * time.Duration(xRayTimeout))
73+
fmt.Println("\txRayCheck2 ok")
74+
return xRayTimeout
75+
}
76+
77+
func AirportCheck() int {
78+
total := 0
79+
total += idCheck2()
80+
total += bodyCheck2()
81+
total += xRayCheck2()
82+
return total
83+
}
84+
85+
func showSerialization() {
86+
println("start")
87+
total := 0
88+
passager := 30
89+
for i := 0; i < passager; i++ {
90+
total += AirportCheck()
91+
}
92+
println("total:", total)
93+
println("end")
94+
}
95+
96+
func main() {
97+
showSerialization()
98+
}

chapter6/sources/concurrency-design-airport-securitycheck-2.go

+62-4
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,19 @@ const (
1010

1111
func idCheck(id int) int {
1212
time.Sleep(time.Millisecond * time.Duration(idCheckTmCost))
13-
print("\tgoroutine-", id, ": idCheck ok\n")
13+
println("\t goroutine ", id, ": idCheck ok")
1414
return idCheckTmCost
1515
}
1616

1717
func bodyCheck(id int) int {
1818
time.Sleep(time.Millisecond * time.Duration(bodyCheckTmCost))
19-
print("\tgoroutine-", id, ": bodyCheck ok\n")
19+
println("\t goroutine ", id, ": bodyCheck ok")
2020
return bodyCheckTmCost
2121
}
2222

2323
func xRayCheck(id int) int {
2424
time.Sleep(time.Millisecond * time.Duration(xRayCheckTmCost))
25-
print("\tgoroutine-", id, ": xRayCheck ok\n")
25+
println("\t goroutine ", id, ": xRayCheck ok")
2626
return xRayCheckTmCost
2727
}
2828

@@ -64,7 +64,7 @@ func max(args ...int) int {
6464
return n
6565
}
6666

67-
func main() {
67+
func showConcurrency1() {
6868
total := 0
6969
passengers := 30
7070
c := make(chan struct{})
@@ -80,3 +80,61 @@ func main() {
8080
total = max(<-c1, <-c2, <-c3)
8181
println("total time cost:", total)
8282
}
83+
84+
func AirCheck2(id int) int {
85+
println("start exec goroutine: ", id)
86+
total := 0
87+
88+
total += idCheck(id)
89+
total += bodyCheck(id)
90+
total += xRayCheck(id)
91+
println("end exec goroutine: ", id)
92+
return total
93+
}
94+
95+
func start2(id int, f func(int) int, signal chan struct{}) chan int {
96+
c := make(chan int)
97+
go func() {
98+
total := 0
99+
for {
100+
_, ok := <-signal
101+
if !ok {
102+
c <- total
103+
return
104+
}
105+
total += f(id)
106+
}
107+
}()
108+
return c
109+
}
110+
111+
func max2(ints ...int) int {
112+
r := 0
113+
for i := 0; i < len(ints); i++ {
114+
if ints[i] > r {
115+
r = ints[i]
116+
}
117+
}
118+
return r
119+
}
120+
121+
func showConcurrency2() {
122+
println("start ")
123+
signal := make(chan struct{})
124+
ch1 := start2(1, AirCheck2, signal)
125+
ch2 := start2(2, AirCheck2, signal)
126+
ch3 := start2(3, AirCheck2, signal)
127+
passagers := 30
128+
for i := 0; i < passagers; i++ {
129+
signal <- struct{}{}
130+
}
131+
close(signal)
132+
133+
total := max2(<-ch1, <-ch2, <-ch3)
134+
println("total time cost:", total)
135+
println("end")
136+
}
137+
138+
func main() {
139+
showConcurrency2()
140+
}

chapter6/sources/concurrency-design-airport-securitycheck-3.go

+87-2
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@ func start(id string, f func(string) int, next chan<- struct{}) (chan<- struct{}
4545
}
4646
}
4747
}
48-
4948
}()
5049
return queue, quit, result
5150
}
@@ -90,7 +89,25 @@ func max(args ...int) int {
9089
return n
9190
}
9291

93-
func main() {
92+
func idCheck3(id string) int {
93+
time.Sleep(time.Millisecond * time.Duration(idCheckTmCost))
94+
print("\tgoroutine-", id, "-idCheck: idCheck ok\n")
95+
return idCheckTmCost
96+
}
97+
98+
func bodyCheck3(id string) int {
99+
time.Sleep(time.Millisecond * time.Duration(bodyCheckTmCost))
100+
print("\tgoroutine-", id, "-bodyCheck: bodyCheck ok\n")
101+
return bodyCheckTmCost
102+
}
103+
104+
func xRayCheck3(id string) int {
105+
time.Sleep(time.Millisecond * time.Duration(xRayCheckTmCost))
106+
print("\tgoroutine-", id, "-xRayCheck: xRayCheck ok\n")
107+
return xRayCheckTmCost
108+
}
109+
110+
func showConcurrency3() {
94111
passengers := 30
95112
queue := make(chan struct{}, 30)
96113
newAirportSecurityCheckChannel("channel1", queue)
@@ -105,3 +122,71 @@ func main() {
105122
close(queue) // 为了打印各通道的处理时长
106123
time.Sleep(1000 * time.Second)
107124
}
125+
126+
func start3(id string, f func(string) int, next chan struct{}) (sig chan struct{}, quit chan struct{}, data chan int) {
127+
sig = make(chan struct{}, 10)
128+
quit = make(chan struct{})
129+
data = make(chan int)
130+
131+
go func() {
132+
total := 0
133+
for {
134+
select {
135+
case <-quit:
136+
data <- total
137+
return
138+
case v := <-sig:
139+
total += f(id)
140+
if next != nil {
141+
next <- v
142+
}
143+
}
144+
}
145+
}()
146+
return sig, quit, data
147+
}
148+
149+
func newAirportSecurityCheckChannel2(s string, sig chan struct{}) {
150+
println("newAirportSecurityCheckChannel2 ready")
151+
go func() {
152+
sig3, quit1, data1 := start3(s, xRayCheck3, nil)
153+
sig2, quit2, data2 := start3(s, bodyCheck3, sig3)
154+
sig1, quit3, data3 := start3(s, idCheck3, sig2)
155+
for {
156+
v, ok := <-sig
157+
if !ok {
158+
close(quit1)
159+
close(quit2)
160+
close(quit3)
161+
total := max(<-data1, <-data2, <-data3)
162+
println("gouroutine: ", s, ", total: ", total)
163+
println("gouroutine: ", s, ", closed")
164+
return
165+
}
166+
sig1 <- v
167+
}
168+
}()
169+
}
170+
171+
func showConcurrency33() {
172+
passagers := 30
173+
sig := make(chan struct{}, 30)
174+
newAirportSecurityCheckChannel2("channel1", sig)
175+
newAirportSecurityCheckChannel2("channel2", sig)
176+
newAirportSecurityCheckChannel2("channel3", sig)
177+
178+
time.Sleep(5 * time.Second)
179+
for i := 0; i < passagers; i++ {
180+
sig <- struct{}{}
181+
}
182+
time.Sleep(5 * time.Second)
183+
println("main done1")
184+
close(sig)
185+
time.Sleep(1000 * time.Second)
186+
println("main done")
187+
}
188+
189+
func main() {
190+
// showConcurrency3()
191+
showConcurrency33()
192+
}

chapter6/sources/go-channel-case-1.go

+6-1
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,13 @@ func f() {
88
<-c
99
}
1010

11-
func main() {
11+
func showGoChanCase1() {
1212
go f()
1313
c <- 5
1414
println(a)
1515
}
16+
17+
func main() {
18+
showGoChanCase1()
19+
20+
}
1.69 MB
Binary file not shown.

chapter6/sources/go-scheduler-model-case1.go

+2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package main
22

33
import (
44
"fmt"
5+
"runtime"
56
"time"
67
)
78

@@ -11,6 +12,7 @@ func deadloop() {
1112
}
1213

1314
func main() {
15+
fmt.Println(runtime.NumCPU())
1416
go deadloop()
1517
for {
1618
time.Sleep(time.Second * 1)

0 commit comments

Comments
 (0)