Home  >  Article  >  Backend Development  >  How to Ensure Mutual Exclusion in Concurrent Goroutines Using Mutexes?

How to Ensure Mutual Exclusion in Concurrent Goroutines Using Mutexes?

Patricia Arquette
Patricia ArquetteOriginal
2024-10-30 16:38:26549browse

How to Ensure Mutual Exclusion in Concurrent Goroutines Using Mutexes?

Mutual Exclusion in Concurrent Goroutines: Achieving Code Isolation

In concurrent programming, it's crucial to have mechanisms in place to prevent multiple goroutines from executing the same code simultaneously. This ensures data integrity and prevents unexpected behavior.

Consider the following scenario:

<code class="go">Routine 1 {
do something

*Send int to Routine 2
Send int to Routine 3
Print Something
Print Something*

do something
}

Routine 2 {
do something

*Send int to Routine 1
Send int to Routine 3
Print Something
Print Something*

do something
}

Routine 3 {
do something

*Send int to Routine 1
Send int to Routine 2
Print Something
Print Something*

do something
}</code>

Here, while the code sections between do something markers are executing, we want to prevent control from flowing to other goroutines. For instance, when Routine1 is executing the portion within stars, Routine2 and Routine3 should be blocked.

Achieving Mutual Exclusion with WaitGroup

One approach to enforce mutual exclusion is to use a sync.WaitGroup. However, this technique is not applicable in this scenario because it lacks the ability to block goroutines selectively.

Utilizing Mutexes for Isolation

A more effective solution is to employ sync.Mutex. A mutex ensures that only one goroutine can possess it at any given time. Here's how to implement mutual exclusion using mutexes:

<code class="go">package main

import (
    "fmt"
    "sync"
)

var (
    mutex1, mutex2, mutex3 sync.Mutex
)

func Routine1() {
    mutex1.Lock()
    // do something
    for i := 0; i < 200; i++ {
        mutex2.Lock()
        mutex3.Lock()
        fmt.Println("value of z")
        mutex2.Unlock()
        mutex3.Unlock()
    }
    // do something
    mutex1.Unlock()
}

func Routine2() {
    mutex2.Lock()
    // do something
    for i := 0; i < 200; i++ {
        mutex1.Lock()
        mutex3.Lock()
        fmt.Println("value of z")
        mutex1.Unlock()
        mutex3.Unlock()
    }
    // do something
    mutex2.Unlock()
}

func Routine3() {
    mutex3.Lock()
    // do something
    for i := 0; i < 200; i++ {
        mutex1.Lock()
        mutex2.Lock()
        fmt.Println("value of z")
        mutex1.Unlock()
        mutex2.Unlock()
    }
    // do something
    mutex3.Unlock()
}

func main() {
    go Routine1()
    go Routine2()
    Routine3()
}</code>

In this code:

  • We define a mutex for each goroutine (mutex1, mutex2, mutex3).
  • In each goroutine (Routine1, Routine2, Routine3), we lock our mutex at the beginning and unlock it at the end, protecting the critical section within.
  • When a goroutine attempts to lock a mutex that is already locked by another goroutine, it will block until the mutex becomes available.

As a result, the print statements inside each goroutine will execute one at a time, ensuring that no other goroutines can access those lines until the current goroutine has released its lock.

The above is the detailed content of How to Ensure Mutual Exclusion in Concurrent Goroutines Using Mutexes?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn