# Deadlocks, Livelocks, and Starvation

#### Deadlocks

*= program in which all concurrent processes are waiting on one another.*

{% code lineNumbers="true" %}

```go
package main

import (
	"fmt"
	"sync"
)

func main() {
	var wg sync.WaitGroup
	ch1 := make(chan int)
	ch2 := make(chan int)

	wg.Add(1)
	go func() {
		defer wg.Done()
		// Attempting to send data to ch2, but no one is receiving.
		ch2 <- 42
	}()

	wg.Add(1)
	go func() {
		defer wg.Done()
		// Attempting to send data to ch1, but no one is receiving.
		ch1 <- 23
	}()

	wg.Wait()
}
```

{% endcode %}

#### Livelocks

*= programs that are actively performing concurrent operations, but these operations do nothing to move the state of the program forward.*

{% code overflow="wrap" lineNumbers="true" %}

```go
/* Two goroutines are trying to access a shared resource (condition) protected by a mutex (mu). 
They repeatedly check the condition and take actions to resolve the conflict. However, their actions lead to an ongoing conflict without making progress, resulting in a livelock.*/

package main

import (
	"fmt"
	"sync"
)

func main() {
	var mu sync.Mutex
	condition := true

	go func() {
		for {
			mu.Lock()
			if condition {
				mu.Unlock()
				continue
			}
			fmt.Println("Goroutine 1")
			condition = true
			mu.Unlock()
		}
	}()

	go func() {
		for {
			mu.Lock()
			if !condition {
				mu.Unlock()
				continue
			}
			fmt.Println("Goroutine 2")
			condition = false
			mu.Unlock()
		}
	}()

	select {}
}
```

{% endcode %}

#### Starvation

*= any situation where a concurrent process cannot get all the resources it needs to perform work.*

{% code overflow="wrap" lineNumbers="true" %}

```go
/* One goroutine continually acquires and releases a lock, preventing the starving goroutine from ever acquiring it. */

package main

import (
	"fmt"
	"sync"
)

func main() {
	var mu sync.Mutex

	// Starving goroutine
	go func() {
		mu.Lock()
		fmt.Println("Starving goroutine: acquired the lock")
		mu.Unlock()
	}()

	// Goroutine that keeps the lock
	go func() {
		for {
			mu.Lock()
			fmt.Println("Lock keeper goroutine: acquired the lock")
			mu.Unlock()
		}
	}()

	select {}
}
```

{% endcode %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://dianadarie.gitbook.io/go-guide/concurrency/deadlocks-livelocks-and-starvation.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
