为了账号安全,请及时绑定邮箱和手机立即绑定

如何限制对单个实时资源的并发访问

如何限制对单个实时资源的并发访问

Go
回首忆惘然 2023-05-15 15:02:12
我正在尝试识别或理解适用于我遇到的特定并发编程问题的技术、惯用语。为简单起见,假设我有一个实时图形用户界面 (UI),它始终以 10Hz 的频率在屏幕上重绘。每当一组不同线程的至少一个实例正在运行时,我想在此 UI 上显示一个“忙碌”指示器,并且我希望该指示器在这些线程中正好有 0 个正在运行时停止显示。只要 UI 启动,这些线程就可以随时启动和停止。我目前正在 golang 中实现这个(下面有相关的片段)。但总的来说,我按如下方式解决这个问题:通过 mutex 保护对计数器 int waitCount(请求我们指示“繁忙”的线程数)的R+W 访问waitLock。功能drawStatus():重绘整个 UI(每 100 毫秒发生一次):绘制“忙碌”指示器获取互斥体waitLock如果整数waitCount> 0:释放互斥体waitLock功能startWait():当一个线程需要指示忙碌时:获取互斥体waitLock增量整数waitCount释放互斥体waitLock功能stopWait():当一个线程不再需要指示繁忙时:获取互斥体waitLock递减整数waitCount释放互斥体waitLock对我来说,感觉我没有充分利用 golang 的并发功能并诉诸于我熟悉的互斥体。但即便如此,此代码中仍存在一个错误,其中“忙碌”指示器会过早消失。老实说,我不是在寻找任何人来帮助识别该错误,而是试图传达我感兴趣的特定逻辑。是否有更惯用的 golang 方法来解决这个问题?或者是否有我应该研究的更通用的编程模式?我正在使用的这项技术有任何特定的名称吗?关于正确执行此操作的建议或指示会很棒。谢谢。
查看完整描述

2 回答

?
qq_遁去的一_1

TA贡献1725条经验 获得超7个赞

由于您所做的只是锁定单个计数器,因此您可以简化并仅使用sync/atomic包。AddInt32(&x, 1)在启动 goroutine 和AddInt32(&x, -1)结束时调用。从您的绘图 goroutine调用LoadInt32(&x)



查看完整回答
反对 回复 2023-05-15
?
慕容708150

TA贡献1831条经验 获得超4个赞

它依赖于用例(你可以选择你想要的,并且在你产生错误或达到性能损失之前没有人关心),通道将 Lock 隐藏在里面并使编码更简单,但性能成本很小 - 所以我建议使用通道对于一般用例,除非您正在考虑更高的性能):
在以下情况下使用通道:
1 - 转让所有权
2 - 协调

在以下情况下使用基元:
3 -性能关键
4 - 保护结构
引用的内部状态:第 33 页


由于您使用的是协调 goroutine 数量的软实时 UI,而不是性能关键代码,因此我建议使用通道,我在此示例中简化了您的代码:

package main


import (

    "fmt"

    "math/rand"

    "time"

)


func main() {

    for i := 0; i < 100; i++ {

        go job() // e.g.: run all jobs

    }

    busy := 0

    time.Sleep(10 * time.Millisecond) // or make sure at least on goroutine started

    // 10Hz:

    tick := time.NewTicker(100 * time.Millisecond)

    defer tick.Stop()

    for {

        select {

        case n := <-ch:

            busy += n

        case <-tick.C:

            // forces the UI to redraw all changed screen regions

            fmt.Printf(" %d    \r", busy)

            if busy == 0 {

                return

            }

        }

    }

}


func job() {

    ch <- +1

    time.Sleep(time.Duration(rand.Intn(2000)) * time.Millisecond)

    ch <- -1

}


var ch = make(chan int, 1)


查看完整回答
反对 回复 2023-05-15
  • 2 回答
  • 0 关注
  • 124 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信