Mutexes and wait groups:
goroutines run in same address space so have shared memory access which need to be synchronized.
The variable greetings has data race condition.
Check using.
go run -race racedemo.go
//racedemo.go // An example of a data race condition. // Execute the program like so: "go run -race racedemo.go" to detect the race condition. package main import "fmt" var greetings string var howdyDone chan bool func howdyGreetings() { greetings = "Howdy Gopher!" howdyDone <- true } func main() { howdyDone = make(chan bool, 1) go howdyGreetings() greetings = "Hello Gopher!" fmt.Println(greetings) <-howdyDone }
go run -race mutex.go
// An example of solving the data race condition using a mutex. package main import ( "fmt" "sync" ) var greetings string var howdyDone chan bool var mutex = &sync.Mutex{} func howdyGreetings() { mutex.Lock() greetings = "Howdy Gopher!" mutex.Unlock() howdyDone <- true } func main() { howdyDone = make(chan bool, 1) go howdyGreetings() mutex.Lock() greetings = "Hello Gopher!" fmt.Println(greetings) mutex.Unlock() <-howdyDone }
waitgroup.
// An example of concurrently fetching web site URLs using a WaitGroup. package main import ( "fmt" "io/ioutil" "log" "net/http" "sync" ) func fetchUrl(url string, wg *sync.WaitGroup) { // Decrement the WaitGroup counter once we've fetched the URL defer wg.Done() response, err := http.Get(url) if err != nil { log.Fatal("Failed to fetch the URL, ", url, " and encountered this error: ", err) } else { fmt.Println("Contents of url, ", url, ", is:\n") contents, err := ioutil.ReadAll(response.Body) response.Body.Close() if err != nil { log.Fatal("Failed to read the response body and encountered this error: ", err) } fmt.Println(string(contents), "\n") } } func main() { var wg sync.WaitGroup var urlList = []string{ "http://www.golang.org/", "http://www.google.com/", "http://www.youtube.com/", } // Loop through the list of URLs for _, url := range urlList { // Increment the WaitGroup counter wg.Add(1) // Call the fetchURL function as a goroutine to fetch the URL go fetchUrl(url, &wg) } // Wait for the goroutines that are part of the WaitGroup to finish wg.Wait() }
increment the waitgroup using Add method to tell how many goroutines to wait for.
defere wg.Done() --> defer/wait for surronding fn to return.
No comments:
Post a Comment