8000 answers student question · Abhicodeitout/GolangTraining@50a5aa8 · GitHub
[go: up one dir, main page]

Skip to content

Commit 50a5aa8

Browse files
committed
answers student question
1 parent f9b877e commit 50a5aa8

File tree

2 files changed

+162
-0
lines changed
  • 25_QUESTIONS-FROM-STUDENTS/04_goroutines_closing-chan

2 files changed

+162
-0
lines changed
Lines changed: 48 additions & 0 deletions
10000
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package main
2+
3+
import "fmt"
4+
5+
// THIS CODE DOES NOT RUN
6+
// see next folder for fixed code with notes
7+
8+
var done chan bool
9+
10+
func main() {
11+
done = make(chan bool)
12+
c := fanIn(incrementor("1"), incrementor("2"))
13+
for n := range c {
14+
fmt.Println(n)
15+
}
16+
}
17+
18+
func incrementor(s string) <-chan string {
19+
c := make(chan string)
20+
go func() {
21+
for i := 0; i < 20; i++ {
22+
c <- fmt.Sprintf("Process: "+s+" printing:", i)
23+
}
24+
done <- true
25+
}()
26+
return c
27+
}
28+
29+
// FAN IN
30+
func fanIn(input1, input2 <-chan string) <-chan string {
31+
c := make(chan string)
32+
go func() {
33+
for {
34+
c <- <-input1
35+
}
36+
}()
37+
go func() {
38+
for {
39+
c <- <-input2
40+
}
41+
}()
42+
go func() {
43+
<-done
44+
<-done
45+
close(c)
46+
}()
47+
return c
48+
}
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
)
6+
7+
func main() {
8+
// read NOTE ONE below
9+
c1 := incrementor("1")
10+
c2 := incrementor("2")
11+
// NOTE TWO
12+
// the flow of code continues here in main
13+
// incrementor is called
14+
// launches goroutines
15+
// returns channels which will eventually be closed
16+
// by the code that is running in the goroutines
17+
// launched by incrementor
18+
// program flow in main continues on down vertically here
19+
20+
// NOTE THREE
21+
// you're passing into "fanIn" two channels
22+
// fanIn HAS TO pull values off of those channels
23+
// otherwise: DEADLOCK
24+
// fanIn will need to launch goroutines to pull those values
25+
c := fanIn(c1, c2)
26+
27+
// NOTE SEVEN
28+
// we are held up here
29+
// pulling values off of c
30+
// until c is closed
31+
// and all values have been pulled from c
32+
// at which point ...
33+
for n := range c {
34+
fmt.Println(n)
35+
}
36+
37+
// NOTE EIGHT
38+
// our program is done
39+
// flow of code exits out of main
40+
// program ends
41+
}
42+
43+
func incrementor(s string) <-chan string {
44+
c := make(chan string)
45+
go func() {
46+
for i := 0; i < 20; i++ {
47+
// NOTE NINE
48+
// use Sprint here, or Sprintln, not Sprintf
49+
// this code is formatted for Sprintln
50+
// Sprintf would need this
51+
// c <- fmt.Sprintf("Process: %v, printing %v", s, i)
52+
c <- fmt.Sprint("Process: "+s+" printing:", i)
53+
}
54+
// NOTE ONE
55+
// incrementor
56+
// every time it's called
57+
// create a channel, put values on the channel
58+
// ******** important ********
59+
// have some other goroutine somewhere
60+
// pulling values off the channel
61+
// ***************************
62+
// close the channel
63+
// return that closed channel
64+
// these "incrementor" goroutines are off and running
65+
close(c)
66+
}()
67+
return c
68+
}
69+
70+
// FAN IN
71+
func fanIn(input1, input2 <-chan string) <-chan string {
72+
c := make(chan string)
73+
done := make(chan bool)
74+
75+
// NOTE FOUR
76+
// these goroutines will pull values off the "incrementor" channels
77+
// I'm defining the func to have a channel as a parameter and
78+
// I'm passing the channels in as an argument
79+
// as this is good practice to avoid different channels
80+
// accessing the same data and creating a race condition
81+
// not needed here, but good practice
82+
// and good to know about
83+
84+
go func(x <-chan string) {
85+
for n := range x {
86+
c <-n
87+
}
88+
done <- true
89+
}(input1)
90+
91+
go func(x <-chan string) {
92+
for n := range x {
93+
c <-n
94+
}
95+
done <- true
96+
}(input2)
97+
98+
// NOTE FIVE
99+
// this will signal when we're done writing values to c
100+
go func() {
101+
<-done
102+
<-done
103+
close(c)
104+
}()
105+
106+
// NOTE SIX
107+
// all of the above code
108+
// just flows straight through
109+
// goroutines are launched
110+
// and even though they're not done processing
111+
// program flow comes to here and this func returns
112+
// the channel c
113+
return c
114+
}

0 commit comments

Comments
 (0)
0