<-messageChanmessageChan

但是,这个StackOverflow 问题让我害怕导致无意中的死锁。

我做了什么:

chan int<-chanmap[int]boolt.Fatallen(map[int]bool)
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]booldefer close(c)

无论如何,这就是我学到的。希望这对新的 Golangers 有所帮助。

学习到教训了:

val, isOpen := <-chanisOpenfalsesync.RWMutex.RLock()

 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()

 }