package sync import ( "sync" "testing" "time" . "github.com/smartystreets/goconvey/convey" ) func newSyncRWMutex() RWLocker { return &sync.RWMutex{} } func TestChannelRWMutex(t *testing.T) { testCase := map[string]func() RWLocker{ "go-src": newSyncRWMutex, "rw-mutex_v1": NewRWMutexV1, } Convey("rw_mutex", t, func() { for key, newRWMutexFunc := range testCase { Convey("rw_mutex_"+key, func() { rwLock := newRWMutexFunc() var wg sync.WaitGroup // 读操作示例 for i := 0; i < 5; i++ { wg.Add(1) go func(id int) { defer wg.Done() rwLock.RLock() defer rwLock.RUnlock() //fmt.Printf("Reader %d is reading...\n", id) time.Sleep(time.Millisecond * 500) }(i) } // 写操作示例 for i := 0; i < 2; i++ { wg.Add(1) go func(id int) { defer wg.Done() rwLock.Lock() defer rwLock.Unlock() //fmt.Printf("Writer %d is writing...\n", id) time.Sleep(time.Millisecond * 1000) }(i) } // 等待所有协程完成 wg.Wait() }) } }) } func BenchmarkChannelRWMutex(b *testing.B) { rwLock := NewRWMutexV1() var wg sync.WaitGroup b.ResetTimer() for i := 0; i < b.N; i++ { wg.Add(1) go func() { defer wg.Done() rwLock.RLock() defer rwLock.RUnlock() }() } wg.Wait() }