
有大佬可以帮忙看看 SendToProc 这个函数里 select+slice 会 panic 吗?感谢感谢
func init() { Chan = make(chan *GenData, 500000) } var Chan chan *GenData type SendQueue struct { queue []*GenData size int } type GenData struct { s string } func SendToProc() error { go func() { batchSize := 100 tc := time.NewTicker(time.Millisecond * 100) sq := &SendQueue{ queue: make([]*GenData, 0), size: 0, } for { select { case g := <-Chan: sq.queue = append(sq.queue, g) sq.size++ if sq.size == batchSize { send(sq.queue) sq.queue = sq.queue[:0] sq.size = 0 } case <-tc.C: if sq.size > 0 { send(sq.queue) sq.queue = sq.queue[:0] sq.size = 0 } } } }() return nil } func send(sendList []*GenData) { for i, v := range sendList { fmt.Println(i, v) } } 1 iyear 2023 年 6 月 20 日 不太知道你觉得 panic 的点在哪里 |
3 iyear 2023 年 6 月 20 日 浅看了一下,没有可能造成越界的代码,所以越界肯定不会。不过这个 size ,用 len 代替不好么,同时维护一致性上容易疏忽。 |
5 chenxiankong 2023 年 6 月 20 日 没看出 panic 点,要不把 panic 报错和具体代码行发一下? |
6 AnroZ 2023 年 6 月 20 日 建议: 1. 增加下 goroutine 循环退出的响应 2. 习惯性的在这种 goroutine 函数增加一个 defer 函数 处理下异常 3. len 替换 size 4. 收不到 g chan 100 毫秒后再触发超时是不是更合理些,没必要周期性定时 100 毫秒 |
7 folivora OP @chenxiankong #5 主要是进程挂了,怀疑这个地方有问题 panic 了,想请诸位大佬人眼 debug 下。 |
10 MoYi123 2023 年 6 月 21 日 虽然是一样的, sq.size == batchSize 还是写 sq.size >= batchSize 看着安心一点. |
11 pkoukk 2023 年 6 月 21 日 6# 比较完整了。 一般我们会在 SendQueue 里加一个 context ,select 的时候加一项 ctx.Done()当做退出信号,清空队列里的数据,防止主进程退出时,队列里有东西没被处理掉。 |