V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
folivora
V2EX  ›  Go 编程语言

Go 问题请教

  •  
  •   folivora · 2023-06-20 22:09:00 +08:00 · 1470 次点击
    这是一个创建于 520 天前的主题,其中的信息可能已经有所发展或是发生改变。

    有大佬可以帮忙看看 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)
    	}
    }
    
    
    11 条回复    2023-06-21 14:45:52 +08:00
    iyear
        1
    iyear  
       2023-06-20 22:14:02 +08:00
    不太知道你觉得 panic 的点在哪里
    folivora
        2
    folivora  
    OP
       2023-06-20 22:15:48 +08:00
    @iyear #1 担心数组越界 panic ,我怀疑,代码能力太差了
    iyear
        3
    iyear  
       2023-06-20 22:21:15 +08:00
    浅看了一下,没有可能造成越界的代码,所以越界肯定不会。不过这个 size ,用 len 代替不好么,同时维护一致性上容易疏忽。
    folivora
        4
    folivora  
    OP
       2023-06-20 22:29:50 +08:00
    @iyear #3 感谢大佬,我回头优化下代码 hh
    chenxiankong
        5
    chenxiankong  
       2023-06-20 22:37:31 +08:00
    没看出 panic 点,要不把 panic 报错和具体代码行发一下?
    AnroZ
        6
    AnroZ  
       2023-06-20 22:41:44 +08:00   ❤️ 1
    建议:
    1. 增加下 goroutine 循环退出的响应
    2. 习惯性的在这种 goroutine 函数增加一个 defer 函数 处理下异常
    3. len 替换 size
    4. 收不到 g chan 100 毫秒后再触发超时是不是更合理些,没必要周期性定时 100 毫秒
    folivora
        7
    folivora  
    OP
       2023-06-20 22:46:50 +08:00
    @chenxiankong #5 主要是进程挂了,怀疑这个地方有问题 panic 了,想请诸位大佬人眼 debug 下。
    iyear
        8
    iyear  
       2023-06-20 22:48:27 +08:00
    @AnroZ #6 他的 ticker 作用应该不是超时,他应该是想某个时间段内没达到 batchSize 也发出去防止存留太久
    folivora
        9
    folivora  
    OP
       2023-06-20 23:02:06 +08:00
    @iyear #8 是的,ticker 主要是控制了发送策略,达到 batchSize 或者每隔 0.1s 发送一次。
    MoYi123
        10
    MoYi123  
       2023-06-21 10:28:13 +08:00
    虽然是一样的, sq.size == batchSize 还是写 sq.size >= batchSize 看着安心一点.
    pkoukk
        11
    pkoukk  
       2023-06-21 14:45:52 +08:00
    6# 比较完整了。
    一般我们会在 SendQueue 里加一个 context ,select 的时候加一项 ctx.Done()当做退出信号,清空队列里的数据,防止主进程退出时,队列里有东西没被处理掉。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5778 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 21ms · UTC 02:29 · PVG 10:29 · LAX 18:29 · JFK 21:29
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.