It seems that the "complex" (getC
) function is blocked. I assume the channel is destroyed once it is read therefore I'm wondering how can I share the sC
channel with both getC
function and the main
function without get into deadlock ( current snippet )
package main
func main() {
//simple function and complex function/channel
sC := make(chan string)
go getS(sC)
cC := make(chan string)
go getC(sC, cC)
//collect the functions result
s := <-sC
//do something with `s`. We print but we may want to use it in a `func(s)`
print(s)
//after a while we do soemthing with `c`
c := <-cC
print(c)
}
func getS(sC chan string) {
s := " simple completed "
sC <- s
}
func getC(sC chan string, cC chan string) {
//we do some complex stuff
print("complex is not complicated
")
//Now we need the simple value so we try wait for the s channel.
s := <-sC
c := s + " more "
cC <- c //send complex value
}
You should not try to get value from sC
channel in main function because the only value you send to it is consumed by getC
function in seperate go routine. While trying to read sC
channel main function blocks waiting for something and it never ends. Go routine getS
is finished, go routine getC
has consumed value from channel sC
and has also finished. There is nothing in channel sC
anymore.
The possible solution is to create another channel s2C
and send to it value received from sC
channel.
The complete correct code would look like this:
package main
func main() {
sC := make(chan string)
go getS(sC)
s2C := make(chan string)
cC := make(chan string)
go getC(s2C, cC)
s := <-sC
println(s)
s2C <- s
c := <-cC
println(c)
}
func getS(sC chan string) {
s := " simple completed "
sC <- s
}
func getC(sC chan string, cC chan string) {
s := <-sC
c := s + " more "
cC <- c
}
I should have sent s from getS. Code below
package main
import "time"
func main() {
//simple function and complex function/channel
sC := make(chan string)
go getS(sC)
cC := make(chan string)
go getC(sC, cC)
//collect the functions result
s := <-sC
//do something with `s`. We print but we may want to use it in a `func(s)`
print(s)
//after a while we do soemthing with `c`
c := <-cC
print(c)
}
func getS(sC chan string) {
s := " simple completed
"
sC <- s
print("sent s back so that main can read it too")
sC <- s
}
func getC(sC chan string, cC chan string) {
time.Sleep(1 * time.Second)
//we do some complex stuff
print("complex is not complicated
")
//Now we need the simple value so we try wait for the s channel.
s := <-sC
c := s + " more "
cC <- c //send complex value
}
I think the problem is with the synchronization. Using a sleep may solve the problem. When you send a value on a channel, it should be received on the other end or else it will show deadlock error. package main
import "sync"
import "time"
import "fmt"
var wg sync.WaitGroup
func main() {
sC := make(chan string)
wg.Add(1)
go getS(sC)
cC := make(chan string)
wg.Add(1)
go getC(sC, cC)
time.Sleep(1 * time.Millisecond)
select {
case s := <-sC:
print(s)
case c := <-cC:
print(c)
}
wg.Wait()
}
func getS(sC chan string) {
defer wg.Done()
s := " simple completed "
fmt.Println(s)
sC <- s
}
func getC(sC chan string, cC chan string) {
defer wg.Done()
fmt.Println("complex is not complicated
")
s := <-sC
c := s + " more "
cC <- c //send complex value
}