2 回答

TA貢獻1890條經驗 獲得超9個贊
給你一個更好的主意。問題是您正在讀取單個通道,其中由于您的time.Sleep調用,推送到該通道上的值按任意順序排列。如果您想同時發出time.Sleep調用來模擬并發的長時間運行的進程,您需要做的是讓每個 goroutine 將結果寫入一個通道。
通過這種方式,您可以遍歷阻塞的結果通道的有序列表,直到可以從中讀取下一個通道(與此答案中的輸出隊列相同的想法在多線程管道中維護順序)名稱更改以使事情更容易跟蹤:
package main
import(
"fmt"
"math/rand"
"time"
"strconv"
)
func main(){
var jobs []chan string
for i := 0; i<10; i++{
job := make(chan string)
jobs = append(jobs, job)
go testfun(i, job)
}
for _, result := range jobs {
fmt.Println(<-result)
}
}
func testfun(i int, job chan<- string){
var innerJobs []chan int
time.Sleep(time.Millisecond*time.Duration(int64(rand.Intn(10))))
for j := 0; j<10; j++ {
innerJob := make(chan int)
innerJobs = append(innerJobs, innerJob)
go testfun2(j, innerJob)
}
tempStr := strconv.FormatInt(int64(i),10)+" - "
for _, result := range innerJobs {
tempStr = tempStr + strconv.FormatInt(int64(<-result),10)
}
job <- tempStr
}
func testfun2(j int, innerJob chan<- int){
time.Sleep(time.Millisecond*time.Duration(int64(rand.Intn(10))))
innerJob <- j
}

TA貢獻1995條經驗 獲得超2個贊
一種不同/更有效的方法是使用切片(或數組)并使用sync.WaitGroup:
func main() {
var wg sync.WaitGroup
out := make([]string, 10)
for i := 0; i < len(out); i++ {
wg.Add(1)
go testfun(i, &out[i], &wg)
}
wg.Wait()
for i := 0; i < len(out); i++ {
a := out[i]
fmt.Println(a)
}
}
func testfun(i int, outVal *string, wg *sync.WaitGroup) {
//........
*outVal = tempStr
wg.Done()
}
playground
編輯:也更新了 testfun2 的示例,忘記了。
- 2 回答
- 0 關注
- 278 瀏覽
添加回答
舉報