No, don't use infinite loop.
Synchronization is better done with channels or the facilities of the sync package. The main()
is a goroutine too (main one), so if main
exits before other goroutines, your task remains unfinished.
One way is to use sync.WaitGroup
to wait for other goroutines to finish (see examples 1,2 and 3). Another way is using channels to wait for other goroutines to finish (see examples 4 and 5). I provide some examples so you may choose which one fits to your case:
1- One tx and multi rx (leave channel open), Try this:
package main
import (
"fmt"
"sync"
)
func main() {
go tx()
wg.Add(20)
for i := 1; i <= 20; i++ {
go rx()
}
wg.Wait()
}
func tx() {
for i := 1; i <= 20; i++ {
vChan <- i
}
}
func rx() {
defer wg.Done()
fmt.Println(<-vChan)
}
var wg sync.WaitGroup
var vChan = make(chan int, 10)
2- One tx and one rx (leave channel open), Try this:
package main
import (
"fmt"
"sync"
)
func main() {
go tx()
wg.Add(1)
go rx()
wg.Wait()
}
func tx() {
for i := 1; i <= 20; i++ {
vChan <- i
}
}
func rx() {
defer wg.Done()
for i := 1; i <= 20; i++ {
fmt.Println(<-vChan)
}
}
var wg sync.WaitGroup
var vChan = make(chan int, 10)
3- Closing channel to signal end of tx, Try this:
package main
import (
"fmt"
"sync"
)
func main() {
go tx()
wg.Add(1)
go rx()
wg.Wait()
}
func tx() {
for i := 1; i <= 5; i++ {
vChan <- i
}
close(vChan)
}
func rx() {
defer wg.Done()
for v := range vChan {
fmt.Println(v)
}
}
var wg sync.WaitGroup
var vChan = make(chan int, 10)
4- Closing channel to signal end of tx, using main goroutine for rx, try this:
package main
import (
"fmt"
)
func main() {
go tx()
for v := range vChan {
fmt.Println(v)
}
}
func tx() {
for i := 1; i <= 20; i++ {
vChan <- i
}
close(vChan)
}
var vChan = make(chan int, 10)
5- Using quit channel, try this:
package main
import (
"fmt"
)
func main() {
go tx()
go rx()
<-quit
}
func rx() {
for v := range vChan {
fmt.Println(v)
}
quit <- struct{}{}
}
func tx() {
for i := 10; i <= 15; i++ {
vChan <- i
}
close(vChan)
}
var quit = make(chan struct{}, 1)
var vChan = make(chan int, 10)
output:
10
11
12
13
14
15
6- Multi tx multi rx, try this:
package main
import (
"fmt"
"sync"
)
func main() {
wg.Add(5)
for i := 1; i <= 5; i++ {
go tx()
go rx()
}
wg.Wait()
}
var n = 10
func tx() {
vChan <- n
n++
}
func rx() {
defer wg.Done()
fmt.Println(<-vChan)
}
var wg sync.WaitGroup
var vChan = make(chan int, 10)
7- Multi tx and one rx, try this:
package main
import (
"fmt"
"sync"
)
func main() {
for i := 1; i <= 5; i++ {
wg.Add(1)
go tx()
}
go rx()
wg.Wait()
}
func rx() {
for {
fmt.Println(<-vChan)
wg.Done()
}
}
var n = 20
func tx() {
vChan <- n
n++
}
var wg sync.WaitGroup
var vChan = make(chan int, 10)
I hope this helps.