[英]How to pass time.Duration type to a go function?
我正在學習 GOLANG,特別是它的並發能力。
已嘗試進一步開發 worker_pool 示例之一,以便每個工作人員收到一個工作 ID 和一個工作負載,以工作的隨機持續時間表示。
time.sleep 命令使用持續時間來等待分配的納秒數,這是隨機計算的。
代碼看起來像這樣......
//worker_pool improved example
package main
import "fmt"
import "time"
import "math/rand"
// Here's the worker, of which we'll run several
// concurrent instances. These workers will receive
// work on the `jobs` channel and send the corresponding
// results on `results`. We'll sleep a random number of seconds between
// 1 and 5 to simulate an expensive task.
func worker(id int, jobs <-chan int, loads <-chan time.Duration, results chan<- int) {
for j := range jobs {
fmt.Println("worker", id, "started job", j, time.Now())
time.Sleep(loads*time.Second)
fmt.Println("worker", id, "finished job", j, time.Now())
results <- j * 2
}
}
func main() {
// In order to use our pool of workers we need to send
// them work and collect their results. We make 2
// channels for this.
jobs := make(chan int)
loads := make(chan time.Duration)
results := make(chan int)
// This starts up 3 workers, initially blocked
// because there are no jobs yet.
for w := 1; w <= 3; w++ {
go worker(w, jobs, results)
}
// Here we send 24 `jobs` and then `close` that
// channel to indicate that's all the work we have.
for j := 1; j <= 24; j++ {
jobs <- j
r := rand.New(rand.NewSource(99))
load := r.Int63n(5000000)
loads <- load
}
close(jobs)
close(loads)
// Finally we collect all the results of the work.
for a := 1; a <= 24; a++ {
<-results
}
}
我不斷收到此錯誤消息...
prog.go:18:33:無法將負載(類型 <-chan int)轉換為類型 time.Duration
prog.go:36:18: 沒有足夠的參數調用 worker have (int, chan int, chan int) want (int, <-chan int, <-chan int, chan<- int)
prog.go:45:15: 不能在發送中使用負載(int64 類型)作為 int 類型
我究竟做錯了什么?
即使您修復了編譯錯誤,您仍然會遇到問題。
//worker_pool improved example
package main
import "fmt"
import "time"
import "math/rand"
// Here's the worker, of which we'll run several
// concurrent instances. These workers will receive
// work on the `jobs` channel and send the corresponding
// results on `results`. We'll sleep a random number of seconds between
// 1 and 5 to simulate an expensive task.
func worker(id int, jobs <-chan int, loads <-chan time.Duration, results chan<- int) {
for j := range jobs {
fmt.Println("worker", id, "started job", j, time.Now())
time.Sleep(<-loads * time.Second)
fmt.Println("worker", id, "finished job", j, time.Now())
results <- j * 2
}
}
func main() {
// In order to use our pool of workers we need to send
// them work and collect their results. We make 2
// channels for this.
jobs := make(chan int)
loads := make(chan time.Duration)
results := make(chan int)
// This starts up 3 workers, initially blocked
// because there are no jobs yet.
for w := 1; w <= 3; w++ {
go worker(w, jobs, loads, results)
}
// Here we send 24 `jobs` and then `close` that
// channel to indicate that's all the work we have.
for j := 1; j <= 24; j++ {
jobs <- j
r := rand.New(rand.NewSource(99))
load := time.Duration(r.Int63n(5000000))
loads <- load
}
close(jobs)
close(loads)
// Finally we collect all the results of the work.
for a := 1; a <= 24; a++ {
<-results
}
}
游樂場: https : //play.golang.org/p/tVdlKFHunKN
輸出:
worker 3 started job 1 2009-11-10 23:00:00 +0000 UTC m=+0.000000001
worker 1 started job 2 2009-11-10 23:00:00 +0000 UTC m=+0.000000001
worker 2 started job 3 2009-11-10 23:00:00 +0000 UTC m=+0.000000001
worker 1 finished job 2 2009-12-27 17:05:41 +0000 UTC m=+4039541.000000001
worker 3 finished job 1 2009-12-27 17:05:41 +0000 UTC m=+4039541.000000001
worker 2 finished job 3 2009-12-27 17:05:41 +0000 UTC m=+4039541.000000001
fatal error: all goroutines are asleep - deadlock!
確實是代碼有問題。
我創建的通道沒有緩沖。 我為作業和結果通道添加了一個 100(每個原始示例)的緩沖區,並且程序運行正常。
//worker_pool improved example
package main
import "fmt"
import "time"
import "math/rand"
func worker(id int, jobs <-chan int, loads <-chan time.Duration, results chan<- int) {
for j := range jobs {
before := time.Now()
fmt.Println("worker", id, "started job", j)
time.Sleep(<-loads)
after := time.Now()
fmt.Println("worker", id, "finished job", j, "in", after.Sub(before))
results <- j
}
}
func main() {
jobs := make(chan int, 100) // Buffered channel
loads := make(chan time.Duration)
results := make(chan int, 100) // Buffered channel
for w := 1; w <= 3; w++ {
go worker(w, jobs, loads, results)
}
for j := 1; j <= 24; j++ {
jobs <- j
r := rand.New(rand.NewSource(int64(j*10)))
loads <- time.Duration(r.Int63n(500000000)) // In nano seconds
}
close(jobs)
close(loads)
for a := 1; a <= 24; a++ {
<-results
}
}
游樂場: https : //play.golang.org/p/bz-JIkD1OoG
我仍然習慣了隨機生成器的邏輯。 給定某個種子,它每次都返回完全相同的數字,在我看來,這違背了隨機性的概念。
部分結果...
worker 3 started job 1
worker 1 started job 2
worker 2 started job 3
worker 1 finished job 2 in 168.00641ms
worker 1 started job 4
worker 3 finished job 1 in 205.826435ms
worker 3 started job 5
worker 3 finished job 5 in 160.909863ms
worker 3 started job 6
worker 2 finished job 3 in 381.707665ms
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.