You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Golang chan是否存在竞态条件?多读写场景下的死锁疑虑

关于Go中多读写goroutine下Chan的死锁与竞态问题

我想搭建一个简单的WebSocket服务器,用chan来做消息分发,比如调用<-messageChan,这个messageChan会有多个写入者和读取者。但参考相关讨论后,我担心这种场景下会意外触发死锁。

为此我写了个测试来验证:

  • 向chan int中填充0到1000的数值;
  • 创建100个goroutine,每个goroutine不断从chan中取值并存入map[int]bool;
  • 最后检查map[int]bool的长度是否为1000,以此判断是否存在竞态条件,若不符合则调用t.Fatal。

但测试一直没有失败,我怀疑自己的测试逻辑有问题,同时也不确定chan在多读写场景下到底会不会引发死锁。

以下是测试代码(main_test.go):

package main

import (
    "log"
    "sync"
    "testing"
)

type MapMux struct {
    sync.RWMutex
    m map[int]bool
    sync.WaitGroup
}

func (mux *MapMux) AddInt(i int) {
    mux.RLock()
    if _, isExist := mux.m[i]; isExist {
        log.Fatal("race condition")
    }
    mux.RUnlock()
    mux.Lock()
    mux.m[i] = true
    mux.Unlock()
    mux.Done()
}

func TestChanRaceCondition(t *testing.T) {
    l := 1000
    c := make(chan int, l)
    defer close(c)
    for i := 0; i < l; i++ {
        c <- i
    }

    mux := MapMux{sync.RWMutex{}, map[int]bool{}, sync.WaitGroup{}}

    mux.Add(l)

    for i := 0; i < 100; i++ {
        go func(key int) {
            for {
                payload := <-c
                log.Printf("go%d: %d", key, payload)
                mux.AddInt(payload)
            }
        }(i)
    }

    mux.Wait()

    if len(mux.m) != l {
        t.Fatal("expected len:", l, ", actual len:", len(mux.m))
    }
}

编辑补充

后续发现代码会检测到map[int]bool存在重复值,问题出在使用了defer close(c),正确的做法是每次从chan取值时都要检查通道是否处于开启状态。

最终总结的经验

  • 单个chan原生支持多个写入者和读取者;
  • 必须始终使用val, isOpen := <-chan的方式检查通道状态,若isOpen为false则要停止对该通道的操作;
  • sync.RWMutex.RLock()只能保证读取的一致性,无法阻止其他goroutine修改map,要注意锁的正确使用逻辑,修正后的示例代码如下:
func (mux *MapMux) AddInt(i int) {
    mux.RLock()
    if _, isExist := mux.m[i]; isExist {
        log.Fatal("race condition")
    }
    mux.RUnlock()
    mux.Lock()
    if _, isExist := mux.m[i]; isExist {
        log.Fatal("race condition")
    }
    mux.m[i] = true
    mux.Unlock()
    mux.Done()
}

内容的提问来源于stack exchange,提问作者Jason Rich Darmawan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 19:05:44