请教这段 go 代码哪里造成阻塞

2018-08-05 11:48:18 +08:00
 whoami9894
func process_kuaidaili() chan Proxy {
	var wg1 sync.WaitGroup
	result := make(result_list, 500)
	index_url := "https://www.kuaidaili.com/free"
	queue := make(task_list, 10) //change count
	for i := 1; i <= 4; i++ {
		queue <- index_url + "/inha/" + strconv.Itoa(i)
		queue <- index_url + "/intr/" + strconv.Itoa(i)
	}
	fmt.Println(len(queue))
	wg1.Add(len(queue))
	for i := 0; i < len(queue); i++ {
		go func() {
			defer wg1.Done()
            //request 函数传 channel 进去,取出一个 URL 发起请求
			resp := request(queue, "www.kuaidaili.com")		
			defer resp.Body.Close()
			defer fmt.Println("exit")
			doc, _ := goquery.NewDocumentFromResponse(resp)
			doc.Find("tr").Each(func(i int, contentSelection *goquery.Selection) {
				_IP := contentSelection.Find("td").Eq(0).Text()
				if reg_ip.Find([]byte(_IP)) != nil {
					_Port := contentSelection.Find("td").Eq(1).Text()
					_Anonymous := contentSelection.Find("td").Eq(2).Text()
					if _Anonymous == "高匿名" {
						_Anonymous = "1"
					} else {
						_Anonymous = "0"
					}
					_SSL := contentSelection.Find("td").Eq(3).Text()
					if _SSL == "HTTPS" {
						_SSL = "1"
					} else {
						_SSL = "0"
					}
					append_proxy := Proxy{
						IP:        _IP,
						Port:      _Port,
						Anonymous: _Anonymous,
						SSL:       _SSL,
					}
					result <- append_proxy
					fmt.Printf("-----%v------\n", len(result))
				}
			})
		}()
	}
	wg1.Wait()
	fmt.Println("return")
	return result
}

main 函数调用

func main() {
	fmt.Println("start")
	aa := process_kuaidaili()
	fmt.Println(len(aa))
}

程序阻塞,输出:

start
8
https://www.kuaidaili.com/free/inha/1
-----1------
-----2------
-----3------
-----4------
-----5------
-----6------
-----7------
-----8------
-----9------
-----10------
-----11------
-----12------
-----13------
-----14------
-----15------
exit
https://www.kuaidaili.com/free/intr/1
exit
https://www.kuaidaili.com/free/inha/2
exit
https://www.kuaidaili.com/free/intr/2
exit
--*--block here--*--

3120 次点击
所在节点    Go 编程语言
11 条回复
XxxxD
2018-08-05 15:18:00 +08:00
这是弄代理池么,不过我不懂 go, 路过
lcorange
2018-08-05 18:01:43 +08:00
--*--block here--*--这里会再往后会报错么?我没法运行你的代码,那几个网页我试了试,刷新太快是不会返回数据的。是不是中间发生了异常,defer wg1.Done() ,这句一直没法执行,一共是 8 个,看日志只消耗了 4 个,导致外部卡在 wg1.Wait() 上
myself659
2018-08-05 20:35:15 +08:00
chan result 在哪里有接收 ?
whoami9894
2018-08-05 21:17:37 +08:00
@XxxxD
是的
whoami9894
2018-08-05 21:22:03 +08:00
@lcorange

不会报错是一直阻塞在这里

函数里三个 defer,正常输出了 exit 的话,倒序就是卡在 io.reader.close 或 wg.done 那里了
whoami9894
2018-08-05 21:24:17 +08:00
@myself659

在另一个函数里接收,这八个网页解析出的 proxy 只有不到两百,channel 缓冲给了 500 不会阻塞在这里
sunznx
2018-08-05 21:30:03 +08:00
```
for i := 0; i < len(queue); i++ {
```

这里有 bug 吧,你 queue 是一直在减的,i = 4,len(queue) = 4
whoami9894
2018-08-05 22:15:58 +08:00
@sunznx

你说的 i==4 是因为前一个循环终值是 4 吗,前一个循环里的 i 作用域只在那个循环里
后面那个循环是新声明的 i=0 ~ 7 开了 8 个 goroutine
sunznx
2018-08-05 22:49:25 +08:00
@whoami9894 len(queue) 是一直在减少的
sagaxu
2018-08-05 22:54:44 +08:00
for i := 0; i < len(queue); i++

改为
qlen := len(queue)
for i := 0; i < qlen; i++
whoami9894
2018-08-05 22:57:48 +08:00
@sunznx
@sagaxu

嗷嗷明白问题了,感谢

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/476983

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX