나는 근근이 살아가고있는 URL 목록을 가지고 있습니다. 내가 뭘하고 싶은지는 성공적으로 긁힌 페이지 데이터를 모두 채널에 저장하고 완료되면 슬라이스에 덤프합니다. 얼마나 많은 성공적인 가져 오기를 얻을지 모르겠으므로 고정 길이를 지정할 수 없습니다. 코드가 wg.Wait()
에 도달하고 모든 wg.Done()
메서드가 호출 될 때까지 기다렸지만 close(queue)
문에 도달하지 못했습니다. 내 wg.Wait()
goroutine 내부가, close(queue)
에 도달 한 포장 자마자goroutine에서 wg.Wait()를 실행할 때 왜 코드가 올바르게 작동합니까?
ports := make(chan string)
toScan := make(chan int)
var wg sync.WaitGroup
// make 100 workers for dialing
for i := 0; i < 100; i++ {
wg.Add(1)
go func() {
defer wg.Done()
for p := range toScan {
ports <- worker(*host, p)
}
}()
}
// close our receiving ports channel once all workers are done
go func() {
wg.Wait()
close(ports)
}()
을 : 비슷한 대답을 찾고, 나는 저자가 비슷한 않는 경우 SO
https://stackoverflow.com/a/31573574/5721702
대답이 건너 온 : 내가 AG를 사용하지 않는 경우
urls := getListOfURLS()
activities := make([]Activity, 0, limit)
queue := make(chan Activity)
for i, activityURL := range urls {
wg.Add(1)
go func(i int, url string) {
defer wg.Done()
activity, err := extractDetail(url)
if err != nil {
log.Println(err)
return
}
queue <- activity
}(i, activityURL)
}
// calling it like this without the goroutine causes the execution to hang
// wg.Wait()
// close(queue)
// calling it like this successfully waits
go func() {
wg.Wait()
close(queue)
}()
for a := range queue {
// block channel until valid url is added to queue
// once all are added, close it
activities = append(activities, a)
}
왜 코드는
close
에 도달하지 않는다
wg.Wait()
에 대한 oroutine? 나는
wg.Wait()
에 도착하기 때문에 모든
defer wg.Done()
문장이 호출되어 결국 정리할 것이라고 생각합니다. 내 채널에서 값을받는 것과 관련이 있습니까?
전체 코드를 표시 할 수 있습니까? –
기본적으로 채널은 버퍼링되지 않습니다. 즉, 전송 된 값을 수신 할 준비가되어있는 해당 수신자가있는 경우에만 전송을 허용합니다. 대기열로 활동을 보내면 그에 상응하는 수신이 차단되고 차단됩니다. 모든 goroutines 마지막으로 wg.wait가 중단됩니다. 두 개 이상의 입력을 버퍼링하는 데 사용할 수있는 버퍼링 된 채널이라는 개념이 있습니다. https://gobyexample.com/channel-buffering –