In Golang, when two processes run concurrently and block each other's path, and to tackle this situation, both processes use different patterns to access the locked resource to complete their processes, it is known as livelock.
Let's look at an illustration below for a better understanding.
In this illustration, both Process X
and Process Y
lock a resource each—Process X
locks Resource A
, while Process Y
locks Resource B
. However, each process needs access to both resources to complete. As a result, Process Y
releases Resource B
to help Process X
complete. Meanwhile, Process X
releases Resource A
to help Process Y
complete. Consequently, neither process gets completed.
Let's look at the coding example for a better understanding.
package mainimport ("fmt""sync""time""runtime")func main() {runtime.GOMAXPROCS(4)type value struct {sync.Mutexid stringlocked bool}lock := func(v *value) {v.Lock()v.locked = true}unlock := func(v *value) {v.Unlock()v.locked = false}move := func(wg *sync.WaitGroup, id string, v1, v2 *value) {defer wg.Done()for i := 0; ; i++ {if i >= 3 {fmt.Println("canceling goroutine...")return}fmt.Printf("%v: Goroutine is locking\n", v1.id)lock(v1) // <1>time.Sleep(10 * time.Second)if v2.locked { // <2>fmt.Printf("%v: Goroutine is , blocked by %v\n", v1.id, v2.id)unlock(v1) // <3>continue}}}a, b, c := value{id: "Process1"}, value{id: "Process2"}, value{id: "Process3"}var wg sync.WaitGroupwg.Add(4)go move(&wg, "first", &a, &b)go move(&wg, "second", &b, &c)wg.Wait()}
If we run the code, we will find a state in which both have been in a state of
Free Resources