Wednesday, September 9, 2020

Golang: Mutexes and wait groups

 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