提交更清晰的测试以及注释
This commit is contained in:
parent
8f7a4f8c58
commit
426f24f720
@ -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 {
|
||||
|
@ -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)
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user