Home  >  Article  >  Backend Development  >  Types and usage of locks in Golang function concurrent programming

Types and usage of locks in Golang function concurrent programming

WBOY
WBOYOriginal
2024-04-18 08:12:02408browse

Go provides three lock types in functional concurrent programming: mutex lock (Mutex), read-write lock (RWMutex), and one-time lock (Once). Mutex locks guarantee exclusive access, read-write locks allow concurrent reads and single writes, and one-time locks ensure that a block of code is executed only once. These locks are used to coordinate access to shared resources and prevent data races. In practice, mutexes ensure data consistency in concurrent web services, preventing concurrent requests from simultaneously modifying shared data structures.

Types and usage of locks in Golang function concurrent programming

Lock types and usage in Go functional concurrent programming

In Go functional concurrent programming, locks are a synchronization mechanism used to coordinate sharing Resource access to prevent data races. Go provides multiple types of locks, each with different characteristics and applicable scenarios.

Mutex lock

Mutex lock (Mutex) is a basic lock that can only allow one goroutine to obtain resources at the same time. It guarantees exclusive access to shared resources.

import (
    "sync"
    "fmt"
)

var (
    mu      sync.Mutex
    counter int
)

func main() {
    for i := 0; i < 1000; i++ {
        go func() {
            mu.Lock()
            counter++
            mu.Unlock()
        }()
    }
    fmt.Println("Final counter value:", counter)
}

Read-write lock

Read-write lock (RWMutex) allows multiple goroutines to read shared resources concurrently, but only one goroutine can write resources at the same time.

import (
    "sync"
    "fmt"
)

var (
    rwmu  sync.RWMutex
    shared []int
)

func main() {
    // 多个 goroutine 并发读取共享切片
    for i := 0; i < 1000; i++ {
        go func() {
            rwmu.RLock()
            fmt.Println("Read:", shared)
            rwmu.RUnlock()
        }()
    }

    // 单独的 goroutine 写入共享切片
    go func() {
        rwmu.Lock()
        shared = append(shared, 1, 2, 3)
        rwmu.Unlock()
    }()
}

Once

Once is a one-time lock used to ensure that a specific block of code is executed only once.

import (
    "sync"
    "fmt"
)

var (
    initOnce sync.Once
    inited   = false
)

func initialize() {
    inited = true
    fmt.Println("Initialized")
}

func main() {
    initOnce.Do(initialize)
    if inited {
        fmt.Println("Already initialized")
    } else {
        fmt.Println("Not initialized")
    }
}

Practical case: ensuring data consistency in concurrent web services

Suppose there is a web service in which multiple concurrent requests need to operate on the same shared data structure. To ensure data consistency, mutex locks can be used to protect the data structure and prevent concurrent requests from modifying it at the same time.

import (
    "sync"
    "net/http"
)

var (
    mu      sync.Mutex
    clients map[string]*http.Client
)

func main() {
    http.HandleFunc("/addClient", func(w http.ResponseWriter, r *http.Request) {
        mu.Lock()
        clients[r.FormValue("name")] = &http.Client{}
        mu.Unlock()
    })
}

In this example, a mutex lock mu is used to protect concurrent access to the clients map, ensuring that only one request can add or modify customer information at the same time , thus avoiding data competition.

The above is the detailed content of Types and usage of locks in Golang function concurrent programming. 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