#### 原文链接
http://books.studygolang.com/gopl-zh/ch8/ch8-06.html
#### 问题描述
对于下面的代码片段,原文中有一段是“这里将命令行参数传入worklist也是在一个另外的goroutine中进行的,这是为了避免channel两端的main goroutine与crawler goroutine都尝试向对方发送内容,却没有一端接收内容时发生死锁”。没有明白这里“为了避免channel两端的main goroutine与crawler goroutine都尝试向对方发送内容”是什么意思?
如果不在另外的goroutine中执行`worklist <- os.Args[1:]`,main goroutine中执行完`worklist <- os.Args[1:]`后直接死锁,之后for循环中的crawler goroutine根本不会执行,何来的“channel两端的main goroutine与crawler goroutine都尝试向对方发送内容”?
```
func main() {
worklist := make(chan []string)
// Start with the command-line arguments.
go func() { worklist <- os.Args[1:] }()
// Crawl the web concurrently.
seen := make(map[string]bool)
for list := range worklist {
for _, link := range list {
if !seen[link] {
seen[link] = true
go func(link string) {
worklist <- crawl(link)
}(link)
}
}
}
}
```
更多评论
Hi, 命令行参数放在另一个goroutine 的原因是,这里用的worklist是一个不带缓存的Channels, 不带缓存的Channels在"读/写"的时候,都会产生阻塞,直到有另一个goroutine会"写/读"这个Channels,
所以, 代码修改为直接给worklist赋值的如下:
```go
func main() {
worklist := make(chan []string)
// Start with the command-line arguments.
worklist <- os.Args[1:]
// 这里main gogroutine 会阻塞住,直到worklist 在另一个goroutine被写入。
// 所以,为了避免被main goroutine被阻塞住,需要在这里新开一个goroutine.
// Crawl the web concurrently.
seen := make(map[string]bool)
```
#1
<a href="/user/huazonglin" title="@huazonglin">@huazonglin</a> 谢谢答复,我理解命令行参数放在goroutine中的必要性,只是没太理解原文中的说明文字,其实有点抠字眼了哈。结帖吧~
#3