提交更清晰的测试以及注释

This commit is contained in:
liuxiaobo 2025-09-02 21:52:56 +08:00
parent 8f7a4f8c58
commit 426f24f720
2 changed files with 45 additions and 9 deletions

View File

@ -6,6 +6,13 @@ import (
"sync"
)
/*
原生chan主张谁申请谁负责关闭但实际项目中权责往往没有这么清晰
有时候会出现多个协程对同一个chan写入的情况此时chan被某一个协程关闭另一个正在写入会导致panic
如果对原生chan关闭多次也会panic原生chan更适合一写一读或多读的场景生产者负责chan生命周期消费者只负责读
SafeChan可以多写多读多关闭而不会panic
*/
type ByteChan = SafeChan[[]byte]
type SafeChan[T any] struct {

View File

@ -1,16 +1,39 @@
package safeChan
import (
"github.com/fox/fox/ksync"
"github.com/fox/fox/log"
"testing"
"time"
)
func TestSafeChan(t *testing.T) {
ch := NewSafeChan[string](12)
func initLog() {
log.Open("test.log", log.DebugL)
}
// go func() {
_ = ch.Write("hello")
t.Log("write hello. 剩余数量:", ch.Size())
// }()
func OriginChanPanic(t *testing.T) {
och := make(chan string, 10)
go func() {
och <- "hello"
t.Log("write hello")
close(och)
//close(och) // 多次关闭也会panic
}()
time.Sleep(time.Millisecond)
t.Log("origin chan was closed")
ksync.GoSafe(func() {
och <- "world"
}, nil)
}
func SafeChanNoPanic(t *testing.T) {
ch := NewSafeChan[string](12)
go func() {
_ = ch.Write("hello")
t.Log("write hello. 剩余数量:", ch.Size())
}()
ch.Close()
if err := ch.Write("zzz"); err != nil {
t.Log("write zzz err.", err)
@ -20,9 +43,6 @@ func TestSafeChan(t *testing.T) {
for {
select {
case <-ch.ctx.Done():
t.Log("done")
breakNum++
case v, ok := <-ch.Reader():
if ok {
t.Log("read", v, " 剩余数量:", ch.Size())
@ -41,3 +61,12 @@ func TestSafeChan(t *testing.T) {
}
}
func TestSafeChan(t *testing.T) {
initLog()
OriginChanPanic(t)
time.Sleep(time.Second * 1)
SafeChanNoPanic(t)
// 防止主协程过早退出导致go协程里无法打印
time.Sleep(time.Second * 1)
}