【发布时间】:2017-10-05 18:44:18
【问题描述】:
我正在尝试创建一个将字符串发送到 goroutine 池(通过通道)的程序。一旦 goroutine 完成他们的工作,他们就会发送一些结果(通过其他渠道)。
代码是:
package main
import "fmt"
import "os"
import "sync"
import "bufio"
func worker(linkChan <-chan string, outChan chan<- string, wg *sync.WaitGroup, jobId int) {
defer wg.Done()
for url := range linkChan {
// ...
outChan <- url
}
}
func main() {
lCh := make(chan string)
wg := new(sync.WaitGroup)
outCh := make(chan string)
urls := []string{}
if len(os.Args) > 1 {
for _, link := range os.Args[1:] {
urls = append(urls, link)
}
} else {
s := bufio.NewScanner(os.Stdin)
for s.Scan() {
urls = append(urls, s.Text())
}
}
num_worker := 10
for i := 0; i < num_worker; i++ {
wg.Add(1)
go worker(lCh, outCh, wg, i)
}
for _, link := range urls {
lCh <- link
}
close(lCh)
for res := range outCh {
fmt.Printf("%s\n", res)
}
close(outCh)
wg.Wait()
}
运行 echo "something" | ./main 会导致死锁。
据我了解,close(lCh) 应该停止 for url := range linkChan 循环。我错了吗(自从代码死锁以来似乎如此)?
我该如何解决这个死锁?
感谢您的回答。
【问题讨论】:
-
我没有时间调试这段代码,但我看到您在循环中以不可预知的方式使用 goroutine。见github.com/golang/go/wiki/…
-
不可预知的方式是我将循环索引 (
i) 传递给 goroutine 或者我正在使用url迭代器? -
循环索引必须这样做:
go func(i int) { worker(lCh, outCh, wg, i); }(i)