douxian8883 2018-12-11 05:51
浏览 32
已采纳

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

I'm trying to identify or understand an appropriate technique, idiom, whatever for a specific concurrent programming problem I'm having.

For simplicity's sake, assume I have a real-time graphical user interface (UI) that is redrawn on screen at 10Hz always and forever.

I would like to display a "Busy" indicator on this UI whenever at least one instance of a group of different threads are running, and I want that indicator to stop displaying when precisely 0 of these threads are running. These threads could feasibly be started and stopped at any time as long as the UI is up.

I'm currently implementing this in golang (with relevant snippets further below). But in general, I'm solving this as follows:

  • Keep R+W access to a counter int waitCount (number of threads requesting we indicate "Busy") protected via mutex waitLock.

  • function drawStatus(): Redraw the entire UI (occurs every 100ms):

    1. acquire mutex waitLock
    2. if int waitCount > 0:
      1. draw the "Busy" indicator
    3. release mutex waitLock
  • function startWait(): When a thread needs to indicate busy:

    1. acquire mutex waitLock
    2. increment int waitCount
    3. release mutex waitLock
  • function stopWait(): When a thread no longer needs to indicate busy:

    1. acquire mutex waitLock
    2. decrement int waitCount
    3. release mutex waitLock

To me, it feels like I'm not taking full advantage of golang's concurrency facilities and resorting to the mutexes I'm familiar with. But even still, there is a bug in this code wherein the "Busy" indicator gets dismissed prematurely.

I'm honestly not looking for anyone to help identify that bug, but rather I'm trying to convey the specific logic I'm interested in. Is there a more idiomatic golang way to approach this problem? Or is there a more general programming pattern that I should investigate? Does this technique I'm using have any particular name? And suggestions or pointers on doing this properly would be great. Thanks.


And here's some doctor'd up snippets that implement the above logic

    var WaitCycle = [...]rune{'
  • 写回答

2条回答 默认 最新

  • duanruanxian5028 2018-12-11 06:19
    关注

    Since all you're doing is locking on a single counter, you could simplify and just use the sync/atomic package. Call AddInt32(&x, 1) when starting a goroutine, and AddInt32(&x, -1) when ending it. Call LoadInt32(&x) from your drawing goroutine.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 微信会员卡等级和折扣规则
  • ¥15 微信公众平台自制会员卡可以通过收款码收款码收款进行自动积分吗
  • ¥15 随身WiFi网络灯亮但是没有网络,如何解决?
  • ¥15 gdf格式的脑电数据如何处理matlab
  • ¥20 重新写的代码替换了之后运行hbuliderx就这样了
  • ¥100 监控抖音用户作品更新可以微信公众号提醒
  • ¥15 UE5 如何可以不渲染HDRIBackdrop背景
  • ¥70 2048小游戏毕设项目
  • ¥20 mysql架构,按照姓名分表
  • ¥15 MATLAB实现区间[a,b]上的Gauss-Legendre积分