forked from GoesToEleven/GolangTraining
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
f9b877e
commit 50a5aa8
Showing
2 changed files
with
162 additions
and
0 deletions.
There are no files selected for viewing
48 changes: 48 additions & 0 deletions
48
25_QUESTIONS-FROM-STUDENTS/04_goroutines_closing-chan/01_broken-code/main.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
package main | ||
|
||
import "fmt" | ||
|
||
// THIS CODE DOES NOT RUN | ||
// see next folder for fixed code with notes | ||
|
||
var done chan bool | ||
|
||
func main() { | ||
done = make(chan bool) | ||
c := fanIn(incrementor("1"), incrementor("2")) | ||
for n := range c { | ||
fmt.Println(n) | ||
} | ||
} | ||
|
||
func incrementor(s string) <-chan string { | ||
c := make(chan string) | ||
go func() { | ||
for i := 0; i < 20; i++ { | ||
c <- fmt.Sprintf("Process: "+s+" printing:", i) | ||
} | ||
done <- true | ||
}() | ||
return c | ||
} | ||
|
||
// FAN IN | ||
func fanIn(input1, input2 <-chan string) <-chan string { | ||
c := make(chan string) | ||
go func() { | ||
for { | ||
c <- <-input1 | ||
} | ||
}() | ||
go func() { | ||
for { | ||
c <- <-input2 | ||
} | ||
}() | ||
go func() { | ||
<-done | ||
<-done | ||
close(c) | ||
}() | ||
return c | ||
} |
114 changes: 114 additions & 0 deletions
114
25_QUESTIONS-FROM-STUDENTS/04_goroutines_closing-chan/02_fixed-code/main.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
package main | ||
|
||
import ( | ||
"fmt" | ||
) | ||
|
||
func main() { | ||
// read NOTE ONE below | ||
c1 := incrementor("1") | ||
c2 := incrementor("2") | ||
// NOTE TWO | ||
// the flow of code continues here in main | ||
// incrementor is called | ||
// launches goroutines | ||
// returns channels which will eventually be closed | ||
// by the code that is running in the goroutines | ||
// launched by incrementor | ||
// program flow in main continues on down vertically here | ||
|
||
// NOTE THREE | ||
// you're passing into "fanIn" two channels | ||
// fanIn HAS TO pull values off of those channels | ||
// otherwise: DEADLOCK | ||
// fanIn will need to launch goroutines to pull those values | ||
c := fanIn(c1, c2) | ||
|
||
// NOTE SEVEN | ||
// we are held up here | ||
// pulling values off of c | ||
// until c is closed | ||
// and all values have been pulled from c | ||
// at which point ... | ||
for n := range c { | ||
fmt.Println(n) | ||
} | ||
|
||
// NOTE EIGHT | ||
// our program is done | ||
// flow of code exits out of main | ||
// program ends | ||
} | ||
|
||
func incrementor(s string) <-chan string { | ||
c := make(chan string) | ||
go func() { | ||
for i := 0; i < 20; i++ { | ||
// NOTE NINE | ||
// use Sprint here, or Sprintln, not Sprintf | ||
// this code is formatted for Sprintln | ||
// Sprintf would need this | ||
// c <- fmt.Sprintf("Process: %v, printing %v", s, i) | ||
c <- fmt.Sprint("Process: "+s+" printing:", i) | ||
} | ||
// NOTE ONE | ||
// incrementor | ||
// every time it's called | ||
// create a channel, put values on the channel | ||
// ******** important ******** | ||
// have some other goroutine somewhere | ||
// pulling values off the channel | ||
// *************************** | ||
// close the channel | ||
// return that closed channel | ||
// these "incrementor" goroutines are off and running | ||
close(c) | ||
}() | ||
return c | ||
} | ||
|
||
// FAN IN | ||
func fanIn(input1, input2 <-chan string) <-chan string { | ||
c := make(chan string) | ||
done := make(chan bool) | ||
|
||
// NOTE FOUR | ||
// these goroutines will pull values off the "incrementor" channels | ||
// I'm defining the func to have a channel as a parameter and | ||
// I'm passing the channels in as an argument | ||
// as this is good practice to avoid different channels | ||
// accessing the same data and creating a race condition | ||
// not needed here, but good practice | ||
// and good to know about | ||
|
||
go func(x <-chan string) { | ||
for n := range x { | ||
c <-n | ||
} | ||
done <- true | ||
}(input1) | ||
|
||
go func(x <-chan string) { | ||
for n := range x { | ||
c <-n | ||
} | ||
done <- true | ||
}(input2) | ||
|
||
// NOTE FIVE | ||
// this will signal when we're done writing values to c | ||
go func() { | ||
<-done | ||
<-done | ||
close(c) | ||
}() | ||
|
||
// NOTE SIX | ||
// all of the above code | ||
// just flows straight through | ||
// goroutines are launched | ||
// and even though they're not done processing | ||
// program flow comes to here and this func returns | ||
// the channel c | ||
return c | ||
} |