I'm new to Golang and learning to use goroutine. I'm trying to insert into a map[int]string concurrently many strings by goroutines
package main
import (
"fmt"
"sync"
)
func input(m map[int]string, i int, wg *sync.WaitGroup){
m[i] = fmt.Sprintf("line %d
", i+1)
fmt.Print(m[i])
wg.Done()
}
func GetMap(m map[int]string, wg *sync.WaitGroup) {
wg.Add(5)
for i:=0; i<5; i++{
go input(m, i, wg)
}
wg.Wait()
}
func main(){
var wg sync.WaitGroup
m1 := make(map[int]string)
GetMap(m1, &wg)
fmt.Print(m1)
}
Expected:
line 1
line 2
line 5
line 3
line 4
map[0:line 1
1:line 2
2:line 3
3:line 4
4:line 5
]
Results: It's different every time, sometimes it's the expected result sometimes it's like this:
line 5
fatal error: concurrent map writes
line 1
line 2
So why is the result different every time i recompile? Thank you
First of all, you have a race condition on your map. You are sharing it across multiple goroutines without using any synchronization mechanism. Protect it with a sync.Mutex
.
Then, you cannot expect any given order when storing values in a map. In fact, Go's map spec says:
A map is an unordered group of elements of one type
If order matters for your application, then use a slice.