Golang Go语言中请教这段代码哪里造成阻塞
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--*--
Golang Go语言中请教这段代码哪里造成阻塞
更多关于Golang Go语言中请教这段代码哪里造成阻塞的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
这是弄代理池么,不过我不懂 go, 路过
更多关于Golang Go语言中请教这段代码哪里造成阻塞的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
––block here––这里会再往后会报错么?我没法运行你的代码,那几个网页我试了试,刷新太快是不会返回数据的。是不是中间发生了异常,defer wg1.Done() ,这句一直没法执行,一共是 8 个,看日志只消耗了 4 个,导致外部卡在 wg1.Wait() 上
chan result 在哪里有接收 ?
是的
不会报错是一直阻塞在这里
函数里三个 defer,正常输出了 exit 的话,倒序就是卡在 io.reader.close 或 wg.done 那里了
在另一个函数里接收,这八个网页解析出的 proxy 只有不到两百,channel 缓冲给了 500 不会阻塞在这里
<br>for i := 0; i < len(queue); i++ {<br>
这里有 bug 吧,你 queue 是一直在减的,i = 4,len(queue) = 4
你说的 i==4 是因为前一个循环终值是 4 吗,前一个循环里的 i 作用域只在那个循环里
后面那个循环是新声明的 i=0 ~ 7 开了 8 个 goroutine
len(queue) 是一直在减少的
for i := 0; i < len(queue); i++
改为
qlen := len(queue)
for i := 0; i < qlen; i++
嗷嗷明白问题了,感谢
当然,我很乐意帮助你分析Go语言代码中的阻塞问题。不过,由于你没有提供具体的代码片段,我将基于一些常见的情况进行解释,希望这些能帮助你找到问题所在。
在Go语言中,常见的阻塞情况包括:
-
死锁(Deadlock):当两个或多个goroutine互相等待对方持有的锁时,会发生死锁。检查代码中的锁使用,确保每次加锁后都有对应的解锁操作。
-
通道(Channel)阻塞:当向一个无缓冲或满缓冲的通道发送数据时,或从一个空缓冲的通道接收数据时,goroutine会阻塞。确保发送和接收操作都能匹配上,避免单方面的等待。
-
I/O操作阻塞:网络请求、文件读写等I/O操作可能会阻塞。使用goroutine和通道来处理这些操作,可以保持程序的并发性。
-
同步原语(Sync Primitives):如
sync.WaitGroup
、sync.Mutex
、sync.Cond
等,使用不当也可能导致阻塞。确保正确地管理这些同步原语的状态。
为了更具体地定位问题,你可以:
- 使用Go的race detector(通过运行
go run -race your_program.go
)来检测数据竞争和死锁。 - 检查所有通道的发送和接收操作,确保它们都能正确匹配。
- 审查代码中所有的锁和同步原语的使用,确保它们不会导致死锁或不必要的等待。
如果可能,提供具体的代码片段将有助于更精确地诊断问题。