일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- tour of go
- 알고리즘
- LOB
- BOJ
- a tour of go
- JUCE 튜토리얼
- C++
- c++ heap
- OS
- 공룡책
- C++ gui 라이브러리
- JUCE라이브러리
- go
- C++ gui
- JUCE library
- 자료구조
- go channel
- 백준
- Nebula
- JUCE
- 연결리스트
- C++ library
- 운영체제
- vim-go
- gui
- 리듬게임
- C언어
- 코딩
- Docker
- 프로그래밍
- Today
- Total
CafeM0ca
[Go] A Tour of Go Exercise: Web Crawler 본문
tour.golang.org/concurrency/10
마지막 문제다.
웹 크롤링을 병렬적으로 실행시키면 된다.
Crawl 함수를 수정해야하는데 똑같은 URL에 대해 fetch를 두번 하지 말아야한다.
패치를 할 때는 mutex로 잠궈서 패치시켜주면 동시에 map에 접근할 일을 방지할 수 있다.
먼저 Crawl 함수부터 보자.
depth가 0이 되면 함수를 종료하고 그게 아니면 재귀적으로 Crawl함수를 호출한다.
현재 URL에 대해서 fetcher.Fetch(url)을 통해 크롤링 했다는 도장을 찍어준다.
우리의 목표는 Crawl 함수를 병렬적으로 실행시킴과 동시에 크롤링 했다는 도장을 url당 한번만 찍어주면 된다.
이해하기 쉽게 시각화 해보면 아래와 같다.
최초의 Crawl 함수를 호출하고 Crawl 함수 안에서 goroutine을 통해 병렬적으로 각 Crawl 함수를 실행한다.
이 때, 각 Crawl 함수가 갖고 있는 Fetch들이 실행될 텐데 동시에 접근하는걸 막기 위해 mutex를 걸어주자.
전역변수 하나 만들어주고,
main에서 Map 생성
Crawl 함수에선 해당 Url을 탐색했으면 종료해주고 아니면 goroutine으로 하위 url 재귀적으로 Crawl 호출
fetch 함수에선 defer를 사용해서 unlock은 맨 마지막에 해주고 방문기록을 찍어준다.
하지만 문제가 있다. 메인 스레드가 고루틴들을 기달리지 않고 종료해버린다는 것이다.
고루틴을 정상적으로 종료될 때 까지 기다리게 구현하려면 2가지 방법이 있다.
1. 채널을 사용해서 고루틴이 끝날 때 까지 기달리게 하기
2. A Tour of Go에 안나온 WaitGroup 함수 사용하기 (구글링 해보니 있더라)
여기서는 WaitGroup을 사용해보자. WaitGroup은 sync에 있다.
작성중---
'Programming > Go' 카테고리의 다른 글
[Go] Go 프로젝트 개발 환경 구축 (0) | 2021.01.24 |
---|---|
[Go] JSON encode/decode (0) | 2021.01.09 |
[Go] Mutex (0) | 2020.12.08 |
[Go] A tour of go Exercise: Equivalent Binary Trees 풀이 (0) | 2020.12.08 |
[Go] Goroutine과 channel (0) | 2020.12.07 |