When working with a concurrent program in Go
, we use var mutex sync.Mutex
and then if we have to write execute some synchronized code block, we call mutex.Lock()
and mutex.Unlock()
. Now I have some doubts here:
1) Is there only one instance of mutex
i.e. if mutex
is being used for locking for operation of CodeBlockA, and at the same time some other goroutine B
has to use it for some other CodeBlockB that also uses mutex
, will goroutine B
be blocked till goroutine A
relieves mutex
.
2) Is it possible that we can have more instances of muteness guarding their own dedicated code blocks.
While writing the sample code as reference, I got the answer. if we have var mu sync.Mutex
then Locking and Unlocking of mu
will be serialized. It cannot be locked at the same time at two places which could be totally independent code bases. but if we have var mu1 sync.Mutex
and var mu2 sync.Mutex
then mu1
and mu2
can be locked concurrently. Following is a small program for the POC:
package main
import (
"fmt"
"sync"
"time"
)
var mu sync.Mutex
var mu1 sync.Mutex
var wg sync.WaitGroup
// var anotherBalance int
func code1() {
mu.Lock()
defer mu.Unlock()
fmt.Println("Entering code1")
time.Sleep(1 * time.Second)
fmt.Println("Exiting code1")
}
func code2() {
mu1.Lock()
defer mu1.Unlock()
fmt.Println("Entering code2")
time.Sleep(1 * time.Second)
fmt.Println("Exiting code2")
}
func main() {
wg.Add(1)
go func() {
code1()
wg.Done()
}()
wg.Add(1)
go func() {
code2()
wg.Done()
}()
wg.Wait()
}
And after running it,
Entering code2
Entering code1
Exiting code2
Exiting code1
real 0m1.335s
user 0m0.307s
sys 0m0.069s