Detailed explanation of the synchronization and mutual exclusion mechanism of Goroutines in Golang concurrent programming

PHPz
Release: 2023-07-20 11:25:10
Original
969 people have browsed it

Detailed explanation of the synchronization and mutual exclusion mechanism of Goroutines in Golang concurrent programming

With the popularity of multi-core processors and the continuous improvement of computer performance, how to make full use of multiple processor cores for parallel computing has become a concern for developers an important issue faced. Concurrent programming is one of the key technologies to solve this problem. In Golang, Goroutines and Channels are widely used to implement concurrent programming. Among them, Goroutines are lightweight threads that can achieve high-concurrency task processing. In order to ensure the correct cooperation between multiple Goroutines, synchronization and mutual exclusion mechanisms play a crucial role.

1. The basic concept of Goroutines
In Golang, Goroutines are lightweight threads that can execute concurrently with other Goroutines. Goroutines cost fewer resources to create and destroy than traditional threads and can utilize system resources more efficiently.

Goroutines are created using the keyword "go". The sample code is as follows:

package main

import (
    "fmt"
    "time"
)

func task1() {
    for i := 0; i < 5; i++ {
        fmt.Println("Task 1:", i)
        time.Sleep(time.Millisecond * 500)
    }
}

func task2() {
    for i := 0; i < 5; i++ {
        fmt.Println("Task 2:", i)
        time.Sleep(time.Millisecond * 500)
    }
}

func main() {
    go task1()
    go task2()

    time.Sleep(time.Millisecond * 3000)
}
Copy after login

In the above code, two Goroutines are created through the keyword "go" and execute the task1() and task2() functions respectively. . In the main() function, wait for 3 seconds through the time.Sleep() function to ensure that Goroutines have enough time to complete execution.

2. Synchronization and mutual exclusion mechanism of Goroutines
In actual concurrent programming, multiple Goroutines may need to share certain resources. At this time, synchronization and mutual exclusion mechanisms are needed to ensure correct access to resources.

  1. Synchronization
    In Golang, commonly used synchronization mechanisms include WaitGroup, Mutex and RWMutex.

1.1 WaitGroup
WaitGroup is used to wait for the execution of a group of Goroutines to complete. Its functionality is similar to CountDownLatch in Java. The sample code is as follows:

package main

import (
    "fmt"
    "sync"
    "time"
)

func task(i int, wg *sync.WaitGroup) {
    defer wg.Done()

    fmt.Println("Task", i)
    time.Sleep(time.Millisecond * 500)
}

func main() {
    var wg sync.WaitGroup

    for i := 0; i < 5; i++ {
        wg.Add(1)
        go task(i, &wg)
    }

    wg.Wait()
    fmt.Println("All tasks finished")
}
Copy after login

In the above code, a waiting group wg is created through sync.WaitGroup. Call wg.Add(1) before each Goroutine is executed to increment the waiting group counter by 1, indicating that there is a task that needs to wait. After each Goroutine is executed, call wg.Done() to decrement the waiting group counter by 1, indicating that a task has been completed. Finally, wait for all tasks to be completed through wg.Wait().

1.2 Mutex
Mutex is a mutex lock, used to protect shared resources that can only be accessed by one Goroutine at the same time. The sample code is as follows:

package main

import (
    "fmt"
    "sync"
    "time"
)

var count int
var mutex sync.Mutex

func task(i int, wg *sync.WaitGroup) {
    defer wg.Done()

    mutex.Lock()
    defer mutex.Unlock()

    count++
    fmt.Println("Task", i, "count:", count)
    time.Sleep(time.Millisecond * 500)

    mutex.Lock()
    defer mutex.Unlock()

    count--
}

func main() {
    var wg sync.WaitGroup

    for i := 0; i < 5; i++ {
        wg.Add(1)
        go task(i, &wg)
    }

    wg.Wait()
    fmt.Println("All tasks finished")
}
Copy after login

In the above code, a mutex lockmutex is created through sync.Mutex. In each Goroutine, access to shared resources is protected by calling a pair of mutex.Lock() and mutex.Unlock(). In actual applications, the shared resources that need to be protected can be stored in the structure, and access to the shared resources can be controlled through the mutex lock in the structure.

  1. Mutual exclusion
    In addition to synchronization, sometimes mutual exclusion is also needed to ensure that a certain piece of code can only be executed by one Goroutine at the same time. In Golang, commonly used mutual exclusion mechanisms include Once and Mutex.

2.1 Once
Once is used to ensure that a certain piece of code will only be executed once during the running of the program. The sample code is as follows:

package main

import (
    "fmt"
    "sync"
)

var once sync.Once

func task() {
    fmt.Println("Task executed")
}

func main() {
    for i := 0; i < 5; i++ {
        once.Do(task)
    }
}
Copy after login

In the above code, an Once object once is created through sync.Once. In each Goroutine, calling once.Do(task) ensures that the task() function will only be executed once during the entire program running time.

2.2 Mutex
Mutex can also be used to implement mutual exclusion. The sample code is as follows:

package main

import (
    "fmt"
    "sync"
    "time"
)

var count int
var mutex sync.Mutex

func task(i int, wg *sync.WaitGroup) {
    defer wg.Done()

    mutex.Lock()
    defer mutex.Unlock()

    fmt.Println("Task", i)
    time.Sleep(time.Millisecond * 500)
}

func main() {
    var wg sync.WaitGroup

    for i := 0; i < 5; i++ {
        wg.Add(1)
        go task(i, &wg)
    }

    wg.Wait()
    fmt.Println("All tasks finished")
}
Copy after login

In the above code, by calling mutex.Lock() and mutex.Unlock() to ensure that there can only be one at the same time Goroutine executes the task() function and accesses shared resources.

Summary
Through the introduction of this article, we have learned about the synchronization and mutual exclusion mechanism of Goroutines in Golang concurrent programming. In actual applications, synchronization and mutual exclusion mechanisms are the key to ensuring correct collaboration between multiple Goroutines. Proper use of synchronization and mutual exclusion mechanisms such as WaitGroup, Mutex, and RWMutex can ensure correct access to shared resources, thereby achieving efficient concurrent programming.

The above is the detailed content of Detailed explanation of the synchronization and mutual exclusion mechanism of Goroutines in Golang concurrent programming. For more information, please follow other related articles on the PHP Chinese website!

source:php.cn
Statement of this Website
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
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template