登录
首页 >  Golang >  Go教程

如何使用 Golang 函数安全并发遍历数据结构?

时间:2024-10-25 14:08:13 457浏览 收藏

今日不肯埋头,明日何以抬头!每日一句努力自己的话哈哈~哈喽,今天我将给大家带来一篇《如何使用 Golang 函数安全并发遍历数据结构?》,主要内容是讲解等等,感兴趣的朋友可以收藏或者有更好的建议在评论提出,我都会认真看的!大家一起进步,一起学习!

要安全地并发遍历数据结构,可以使用 Golang 的 sync.Mutex 或 sync.RWMutex 来锁定数据结构,防止并发访问。其中,sync.Mutex 一次仅允许一个 Goroutine 访问,而 sync.RWMutex 允许多个 Goroutine 并发读取,但仅允许一个 Goroutine 写入。

如何使用 Golang 函数安全并发遍历数据结构?

使用 Golang 函数并发安全地遍历数据结构

Golang 提供了一个 sync 包,包含用于实现并发安全的并发原语,可帮助你安全地并发遍历数据结构。

Goroutine

Goroutine 是一个并发执行的函数。要使用 Goroutine 安全地遍历数据结构,可以使用 sync.Mutexsync.RWMutex 来锁定数据结构,防止并发访问。

sync.Mutex

sync.Mutex 是一个互斥锁,一次只允许一个 Goroutine 访问数据结构:

package main

import (
    "fmt"
    "sync"
)

type ConcurrentMap struct {
    m sync.Mutex
    data map[int]string
}

func (cm *ConcurrentMap) Get(key int) (string, bool) {
    cm.m.Lock()
    defer cm.m.Unlock()
    value, ok := cm.data[key]
    return value, ok
}

func main() {
    cm := &ConcurrentMap{
        data: map[int]string{
            1: "a",
            2: "b",
        },
    }

    ch := make(chan string)

    for i := 1; i <= 10; i++ {
        go func(i int) {
            value, ok := cm.Get(i)
            if ok {
                ch <- fmt.Sprintf("key %d: %s", i, value)
            }
        }(i)
    }

    for i := 0; i < 10; i++ {
        fmt.Println(<-ch)
    }
}

sync.RWMutex

sync.RWMutex 是一个读写锁,允许多个 Goroutine 并发读取数据结构,但一次只允许一个 Goroutine 写入:

package main

import (
    "fmt"
    "sync"
)

type ConcurrentMap struct {
    m sync.RWMutex
    data map[int]string
}

func (cm *ConcurrentMap) Get(key int) (string, bool) {
    cm.m.RLock()
    defer cm.m.RUnlock()
    value, ok := cm.data[key]
    return value, ok
}

func (cm *ConcurrentMap) Set(key int, value string) {
    cm.m.Lock()
    defer cm.m.Unlock()
    cm.data[key] = value
}

func main() {
    cm := &ConcurrentMap{
        data: map[int]string{
            1: "a",
            2: "b",
        },
    }

    ch := make(chan string)

    for i := 1; i <= 10; i++ {
        go func(i int) {
            value, ok := cm.Get(i)
            if ok {
                ch <- fmt.Sprintf("key %d: %s", i, value)
            }
        }(i)
    }

    for i := 0; i < 10; i++ {
        cm.Set(i+10, fmt.Sprintf("new value %d", i+10))
    }

    for i := 0; i < 10; i++ {
        fmt.Println(<-ch)
    }
}

今天关于《如何使用 Golang 函数安全并发遍历数据结构?》的内容介绍就到此结束,如果有什么疑问或者建议,可以在golang学习网公众号下多多回复交流;文中若有不正之处,也希望回复留言以告知!

相关阅读
更多>
最新阅读
更多>
课程推荐
更多>