登录
首页 >  Golang >  Go问答

GoLang 并发顺序

来源:stackoverflow

时间:2024-02-11 10:45:23 155浏览 收藏

怎么入门Golang编程?需要学习哪些知识点?这是新手们刚接触编程时常见的问题;下面golang学习网就来给大家整理分享一些知识点,希望能够给初学者一些帮助。本篇文章就来介绍《GoLang 并发顺序》,涉及到,有需要的可以收藏一下

问题内容

我是 golang 新手,有一个用例,其中对类型值的操作必须以顺序方式运行,而对其他类型值的操作可以同时运行。

  1. 假设数据来自流连接(按顺序)
    key_name_1, value_1 
    key_name_2, value_2
    key_name_1, value_1
  2. 现在,key_name_1key_name_2 可以同时被 goroutine 操作。
  3. 但由于下一个流值(第 3 行)又是 key_name_1,因此只有在较早的操作(第 1 行)完成后,该操作才应由 goroutine 处理,否则应等待第一个操作完成后才能应用手术。 为了讨论的方便,我们可以假设操作很简单 将新值添加到先前值。

在 golang 中以尽可能高的性能实现这一目标的正确方法是什么?

确切的用例是数据库更改在队列上进行流式传输,现在,如果某个值发生更改,则重要的是将该操作应用到同一序列上的另一个数据库上,否则一致性将受到影响。冲突很少见,但也有可能发生。


正确答案


作为给定密钥的互斥性的简单解决方案,您可以仅使用引用计数锁的锁定映射。它不是高负载的最佳选择,但可能足以满足您的情况。

type processLock struct {
    mtx      sync.Mutex
    refcount int
}

type locker struct {
    mtx   sync.Mutex
    locks map[string]*processLock
}

func (l *locker) acquire(key string) {
    l.mtx.Lock()
    lk, found := l.locks[key]
    if !found {
        lk = &processLock{}
        l.locks[key] = lk
    }
    lk.refcount++
    l.mtx.Unlock()
    lk.mtx.Lock()
}

func (l *locker) release(key string) {
    l.mtx.Lock()
    lk := l.locks[key]
    lk.refcount--
    if lk.refcount == 0 {
        delete(l.locks, key)
    }
    l.mtx.Unlock()
    lk.mtx.Unlock()
}

只需在处理密钥之前调用 acquire(key) ,并在处理完成后调用 release(key)

Live demo

警告!上面的代码保证了排他性,但不保证顺序。要按顺序解锁,您需要 FIFO mutex

本篇关于《GoLang 并发顺序》的介绍就到此结束啦,但是学无止境,想要了解学习更多关于Golang的相关知识,请关注golang学习网公众号!

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>