...

/

Solution: Write Code with Livelock

Solution: Write Code with Livelock

Check the solution to the challenge of writing code with a livelock condition.

Problem breakdown

Let’s walk through the challenge step by step. Livelock occurs when multiple processes constantly try to resolve an issue by backtracking, reverting, retrying, or rolling back. As per the problem statement, both spouses are overly courteous, and if the other spouse is hungry, they will pass over the spoon. Only two goroutines are involved.

Code walkthrough

Let’s walk through the code.

Press + to interact
package main
import (
"fmt"
"sync"
"time"
"runtime"
)
func main() {
runtime.GOMAXPROCS(4)
type value struct {
sync.Mutex
id string
value1 string
value2 string
locked bool
}
lock := func(v *value) {
v.Lock()
v.locked = true
}
unlock := func(v *value) {
v.Unlock()
v.locked = false
}
move := func(wg *sync.WaitGroup, v1, v2 *value) {
defer wg.Done()
for i := 0; ; i++ {
if i >= 3 {
fmt.Println("canceling goroutine...")
return
}
fmt.Printf("%v: %v \n", v1.id, v1.value1)
lock(v1) // <1>
time.Sleep(2 * time.Second)
fmt.Printf("%v: Checking if %v \n", v1.id, v2.value2)
if v2.locked { // <2>
fmt.Printf("%v: Leaving spoon \n", v1.id)
unlock(v1) // <3>
continue
}
}
}
a, b := value{
id: "Alice",
value1: "I am picking up spoon",
value2: "Alice is hungry",
}, value{
id: "Bob",
value1: "I am picking up spoon",
value2: "Bob is hungry",
}
var wg sync.WaitGroup
wg.Add(2)
go move(&wg, &a, &b)
go move(&wg, &b, &a)
// go move(&wg, &a, &b)
// go move(&wg, &a, &b)
wg.Wait()
}

When we run the code and observe the output, we see that both Alice and Bob ...