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

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

如何在執行一組工作人員之間正確延遲

如何在執行一組工作人員之間正確延遲

Go
不負相思意 2022-10-17 19:41:03
美好的一天,我正在嘗試在工作人員執行之間實現正確的延遲,例如,工作人員需要完成 30 個任務并進入睡眠狀態 5 秒,我如何在代碼中跟蹤已經完成了30 個任務只有在那之后才能睡5秒鐘?下面是創建一個由30 個工作人員組成的池的代碼,這些工作人員依次以無序的方式一次執行 30 個任務,這是代碼:import (    "fmt"    "math/rand"    "sync"    "time")type Job struct {    id       int    randomno int}type Result struct {    job         Job    sumofdigits int}var jobs = make(chan Job, 10)var results = make(chan Result, 10)func digits(number int) int {    sum := 0    no := number    for no != 0 {        digit := no % 10        sum += digit        no /= 10    }    time.Sleep(2 * time.Second)    return sum}func worker(wg *sync.WaitGroup) {    for job := range jobs {        output := Result{job, digits(job.randomno)}        results <- output    }    wg.Done()}func createWorkerPool(noOfWorkers int) {    var wg sync.WaitGroup    for i := 0; i < noOfWorkers; i++ {        wg.Add(1)        go worker(&wg)    }    wg.Wait()    close(results)}func allocate(noOfJobs int) {    for i := 0; i < noOfJobs; i++ {        if i != 0 && i%30 == 0 {            fmt.Printf("SLEEPAGE 5 sec...")            time.Sleep(10 * time.Second)        }        randomno := rand.Intn(999)        job := Job{i, randomno}        jobs <- job    }    close(jobs)}func result(done chan bool) {    for result := range results {        fmt.Printf("Job id %d, input random no %d , sum of digits %d\n", result.job.id, result.job.randomno, result.sumofdigits)    }    done <- true}func main() {    startTime := time.Now()    noOfJobs := 100    go allocate(noOfJobs)    done := make(chan bool)    go result(done)    noOfWorkers := 30    createWorkerPool(noOfWorkers)    <-done    endTime := time.Now()    diff := endTime.Sub(startTime)    fmt.Println("total time taken ", diff.Seconds(), "seconds")}播放:https ://go.dev/play/p/lehl7hoo-kp目前尚不清楚如何確保完成 30 個任務以及在哪里插入延遲,我將不勝感激
查看完整描述

1 回答

?
慕姐8265434

TA貢獻1813條經驗 獲得超2個贊

好的,讓我們從這個工作示例開始:


func Test_t(t *testing.T) {


    // just a published, this publishes result on a chan

    publish := func(s int, ch chan int, wg *sync.WaitGroup) {

        ch <- s // this is blocking!!!

        wg.Done()

    }


    wg := &sync.WaitGroup{}

    wg.Add(100)


    // we'll use done channel to notify the work is done

    res := make(chan int)

    done := make(chan struct{})

    // create worker that will notify that all results were published

    go func() {

        wg.Wait()

        done <- struct{}{}

    }()

    

    // let's create a jobs that publish on our res chan

    // please note all goroutines are created immediately

    for i := 0; i < 100; i++ {

        go publish(i, res, wg)

    }


    // lets get 30 args and then wait

    var resCounter int

forloop:

    for {

        select {

        case ss := <-res:

            println(ss)

            resCounter += 1

            // break the loop

            if resCounter%30 == 0 {

                // after receiving 30 results we are blocking this thread

                // no more results will be taken from the channel for 5 seconds

                println("received 30 results, waiting...")

                time.Sleep(5 * time.Second)

            }

        case <-done:

            // we are done here, let's break this infinite loop

            break forloop

        }

    }

}

我希望這進一步表明它是如何完成的。


那么,您的代碼有什么問題?老實說,它看起來不錯(我的意思是發布了 30 個結果,然后代碼等待,然后是另外 30 個結果,等等),但問題是您想在哪里等待?

我猜有幾種可能:

  • 創建工人(這就是您的代碼現在的工作方式,正如我所見,它以 30 個包發布作業;請注意,您在digit函數中的 2 秒延遲僅適用于執行代碼的 goroutine)

  • 觸發工人(所以“等待”代碼應該在工人函數中,不允許運行更多的工人 - 所以它必須觀察發布了多少結果)

  • 處理結果(這就是我的代碼的工作方式,并且正確的同步在forloop


查看完整回答
反對 回復 2022-10-17
  • 1 回答
  • 0 關注
  • 136 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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