亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

Golang - 在 N 單位時間內執行 X 任務

Golang - 在 N 單位時間內執行 X 任務

Go
嚕嚕噠 2023-03-15 15:03:54
我正在嘗試模擬一個程序,它需要在 N 秒內執行任務中的 X 任務并丟棄其他工作請求當收到 on 的值時,我試圖timer在無限循環中使用 with select <-timer.C,我正在繼續模擬任務,其中包含切片中的所有數據,這些數據受到保護maxLimit并再次將其重置timer為初始持續時間這是代碼     type Pool struct {            // The maximum number of items allowed in pool            maxSize int            //the queue to hold the data            queue []interface{}            // time window for this pool            time time.Duration            //timer for the batch            timer *time.Timer            //channel            ch chan interface{}        }                func NewPool(maxSize int, t int32) *Pool {            p := &Pool{                maxSize: maxSize,                size:    0,                queue:   make([]interface{}, maxSize),                time:    time.Duration(t * int32(time.Second)),                timer:   time.NewTimer(time.Duration(t) * time.Second),                ch:      make(chan interface{}),            }            go p.Schedule()            return p        }                func (p *Pool) Add(ele interface{}) {            p.ch <- ele        }                func (p *Pool) Schedule() {            for {                select {                case <-p.timer.C:                    fmt.Println("Time is over")                    p.queue = make([]interface{}, 0)                    p.timer.Reset(p.time)                    p.flush()                case data := <-p.ch:                    if len(p.queue) < p.maxSize {                        fmt.Println("Addding")                        p.queue = append(p.queue, data)                            }                    //p.flush()                    if !p.timer.Stop() {                        <-p.timer.C                    }                    p.queue = make([]interface{}, 0)                        }                    }                }        但這沒有按預期工作我在這里遺漏了一些東西,你能指導我使用并發模式來滿足這個要求嗎,謝謝
查看完整描述

1 回答

?
MMMHUHU

TA貢獻1834條經驗 獲得超8個贊

添加一些額外的輸出可以幫助您定位問題:


case data := <-p.ch:

? ? fmt.Println("Got Data", len(p.queue), p.maxSize)

? ? if len(p.queue) < p.maxSize {

? ? ? ? p.queue = append(p.queue, data)

? ? }

? ? if !p.timer.Stop() {

? ? ? ? fmt.Println("Draining")

? ? ? ? <-p.timer.C

? ? }

? ? p.queue = make([]interface{}, 0)

}

使用該更改運行輸出為:


Got Data 5 5

Got Data 0 5

Addding

Draining

因此正在處理兩條消息(第一條不會輸出,Adding因為len(p.queue)它是 5;這是因為您將其初始化為大小為 5 -?make([]interface{}, maxSize))??紤]收到消息時代碼在做什么:

  1. 處理queue

  2. 停止計時器

  3. 翻拍queue

現在從文檔中獲取timer.Stop()

Stop 阻止 Timer 觸發。如果調用停止計時器,它返回 true?,如果計時器已經過期或停止,則返回 false 。

在第一次迭代中,它起作用了(計時器停止,如有必要,通道被耗盡)。但是,您在停止計時器后不會重置計時器,因此在第二次迭代時,當您調用時計時器已經停止p.timer.Stop()。這意味著Stop()它將返回false(計時器已經停止?。┎⑶夷鷩L試耗盡通道(但由于計時器已經停止,這將永遠阻塞)。

如何解決這個問題取決于你的目標;我懷疑你是想重置定時器?如果沒有,你可以這樣做:

if p.timer.C != nil && !p.timer.Stop() {

? ? fmt.Println("Draining")

? ? <-p.timer.C

}

p.timer.C = nil // Timer has been stopped (nil channel will block forever)


查看完整回答
反對 回復 2023-03-15
  • 1 回答
  • 0 關注
  • 153 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號