为了账号安全,请及时绑定邮箱和手机立即绑定

Go中的并发和超时

Go中的并发和超时

Go
慕森卡 2021-10-25 17:05:12
这个围棋程序:package mainimport (    "fmt"    "time")func main() {    start := time.Now()    sleep_durations := []int{8100, 1000, 2500, 500, 6000}    // sleep_durations := []int{8100, 1000, 2500, 500}    c := make(chan string)    defer close(c) // close channel when main exits    for index, duration := range sleep_durations {        go sleepy(fmt.Sprintf("sleepy%d: ", index+1), duration, c)    }    fmt.Printf("starting %d sleepys\n", len(sleep_durations))    for range sleep_durations {        select {        case msg := <-c:            fmt.Println("received: ", msg)        case <-time.After(time.Second * time.Duration(5)):            fmt.Println("*** TIMEOUT ***")        }    }    elapsed := time.Since(start)    fmt.Printf("... %d sleepys ran in: %e\n", len(sleep_durations), elapsed.Seconds())}func sleepy(msg string, sleep_ms int, yawn chan string) {    start := time.Now()    sleep := time.Duration(sleep_ms) * time.Millisecond    time.Sleep(sleep) // some sleepy work    yawn <- fmt.Sprintf("%s slept for %s", msg, sleep)    elapsed := time.Since(start)    fmt.Printf("\t%s finished in: %s\n", msg, elapsed)}https://play.golang.org/p/0ioTuKv230有令人困惑的结果。当第 11 行被取消注释时,它不会按预期工作,即time.After5 秒不会发生。但是在第 11 行注释和第 12 行取消注释后,超时确实按预期工作。我是 Go 的新手,但我错过了什么?
查看完整描述

2 回答

?
海绵宝宝撒

TA贡献1809条经验 获得超8个赞

我找到了我要找的东西:


package main


import (

  "fmt"

  "sync"

  "time"

)


func main() {

  var wg sync.WaitGroup

  done := make(chan struct{})

  wq := make(chan interface{})

  worker_count := 2


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

    wg.Add(1)

    go doit(i, wq, done, &wg)

  }


  fmt.Printf("doing work\n")

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

    time.Sleep(time.Millisecond * time.Duration(100))

    wq <- fmt.Sprintf("worker: %d", i)

  }


  fmt.Printf("closing 'done' channel\n")

  close(done)

  fmt.Printf("block/wait until all workers are done\n")

  wg.Wait()

  fmt.Println("all done!")

}


func doit(worker_id int, wq <-chan interface{}, done <-chan struct{}, wg *sync.WaitGroup) {

  fmt.Printf("[%v] is working\n", worker_id)

  defer wg.Done()

  max_time := time.Second * time.Duration(5)

  for {

    select {

    case m := <-wq:

      fmt.Printf("[%v] m => %v\n", worker_id, m)

    case <-done:

      fmt.Printf("[%v] is done\n", worker_id)

      return

    case <-time.After(max_time):

      fmt.Printf("timeout > %s seconds!\n", max_time)

    }

  }

}


查看完整回答
反对 回复 2021-10-25
  • 2 回答
  • 0 关注
  • 145 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信