Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- 실전 데이터 분석 프로젝트
- 스파르타
- 텍스트 분석
- SQL
- 파이썬
- 오블완
- hackerrank
- 중회귀모형
- 웹 스크랩핑
- 프로그래머스
- 스파르타 코딩
- 티스토리챌린지
- 회귀분석
- 내일배움캠프
- MySQL
- 미세먼지
- TiL
- 내일배움카드
- 스파르타코딩
- wil
- 파이썬 완벽 가이드
- 프로젝트
- 파이썬 머신러닝 완벽가이드
- 파이썬 철저 입문
- 파이썬 철저입문
- 파이썬 머신러닝 완벽 가이드
- R
- harkerrank
- Cluster
- 내일배움
Archives
- Today
- Total
OkBublewrap
N배 빠른 크롤링(2) 본문
스레드란?
스레드란 프로세스 내부에 있는 CPU 수행 단위
프로세스는 운영체제로부터 자원을 할당해 실행되는 작업의 단위
ex) 크롬 브라우저 두개 실행하면 두개의 프로세스 실행
threading
- threading은 스레드를 이용하여 한 프로세스에서 2가지 이사으이 일을 동시에 실행할 수 있게 하는 표준 모듈
- 파이썬은 기본적으로 싱글 스레드에서 순차적으로 동작함
- 병렬 처리를 위해서는 별도 작업이 필요함
- 활용 분야
- 대용량 데이터의 처리시간을 줄이기 위해 데이터를 분할하여 병렬로 처리
- 애플리케이션에서 다중 네트워크 통신을 할 때
- 여러 클라이언트의 요청을 동시에 처리하는 서버를 개발할 때
from threading import Thread
import time
# 0부터 10,000,000 까지의 합을 구하는 프로그램
def work(id, start, end, result):
total = 0
for i in range(start, end):
total += i
result.append(total)
return
if __name__ == "__main__":
start = time.time()
START, END = 0, 10000000
result = list()
th1 = Thread(target=work, args=(1, START, END, result)) # 싱글 스레드
th1.start()
th1.join()
th1_elapsed = round(time.time() - start, 2)
print(th1_elapsed, ' 초 경과')
print(f"합계 결과 : {sum(result)}")
# 2.79 초 경과
# 합계 결과 : 49999995000000
if __name__ == "__main__":
start = time.time()
START, END = 0, 10000000
result = list()
th2 = Thread(target=work, args=(2, START, END, result)) # 멀티 스레드
th2.start()
th2.join()
th2_elapsed = round(time.time() - start, 2)
speed_up = round(th1_elapsed/th2_elapsed, 1)
print(th2_elapsed, ' 초 경과')
print(speed_up, ' 배 속도 향상')
print(f"합계 결과: {sum(result)}")
# 1.52 초 경과
# 1.8 배 속도 향상
# 합계 결과: 49999995000000
multiprocessing
파이썬에서 병렬처리를 구현하는 방식은 멀티 쓰레드를 사용하거나 멀티 프로세스를 사용하는 두가지 방법이 있다.
스레드 특징
- 스레드는 가볍지만 cpu 계산 처리를 하는 작업에는 한번에 하나의 쓰레드에서만 작동함
- cpu 작업이 적고 네트워크 통신 또는 파일 읽고 쓰기와 같은 작업 (I/O)이 많은 병렬 처리 프로그램에서 효과적
멀티프로세싱 특징
- 멀티 프로세서와 별개의 메모리를 사용하여 완전히 독립하여 병렬 프로그래밍이 가능
- 여러 개의 CPU가 있는 멀티코어 환경에서 CPU 수 만큼 작업을 나누어 실행 가능
- 프로세스는 각자가 고유한 메모리 영역을 가지기 때문에 더 많은 메모리를 필요
- 각각 프로세스에서 병렬로 cpu 작업을 할 수 있고 이를 이용해 여러 장비에서 동작하는 분산 처리 프로그래밍도 구현이 가능
import multiprocessing
import time
# 0부터 50,000,000 까지의 합을 구하는 프로그램
def work(id, start, end, result):
total = 0
for i in range(start, end):
total += i
result.append(total)
return
if __name__ == "__main__":
start = time.time()
START, END = 0, 50000000
result = list()
# 싱글 프로세스 2번 실행
for i in range(2):
work(1, START, END, result)
print(f'{i+1} 번째 실행')
time_elapsed1 = round(time.time() - start, 2)
print(time_elapsed1, ' 초 경과')
print(f"합계 결과: {sum(result)}")
# 1 번째 실행
# 2 번째 실행
# 10.65 초 경과
# 합계 결과: 2499999950000000
if __name__ == "__main__":
start = time.time()
START, END = 0, 50000000
result = list()
procs = []
for i in range(2):
# 프로세스 수만큼 코어 할당
p = multiprocessing.Process(target=work, args=(i, START, END, result))
p.start()
procs.append(p)
print(f'{i+1} 번째 실행')
for p in procs:
p.join() # 프로세스가 모두 종료될 때까지 대기
time_elapsed2 = round(time.time() - start, 2)
speed_up = round(time_elapsed1/time_elapsed2, 1)
print(time_elapsed2, ' 초 경과')
print(speed_up, ' 배 속도 향상')
print(f"합계 결과: {sum(result)}")
# 1 번째 실행
# 2 번째 실행
# 5.86 초 경과
# 1.8 배 속도 향상
# 합계 결과: 0
결론
1️⃣ 싱글 프로세스 방식에서는 두 번의 계산을 순차적으로 진행하고, 결과를 result에 추가한 후 합계 계산
2️⃣ 멀티프로세스 방식에서는 두 프로세스를 병렬로 실행, result를 안전하게 안되서 잘못된 결과가 나옴
멀티프로세싱에서 여러 프로세스가 동일한 리스트를 수정하면, 경쟁 상태가 발생
이 경우 각 프로세스가 수정한 결과가 덮어씌워져 올바른 결과를 얻을 수 없다.
if __name__ == "__main__":
start = time.time()
START, END = 0, 50000000
result = list()
# Manager를 사용하여 멀티프로세싱에서 안전하게 공유할 수 있는 리스트 생성
manager = multiprocessing.Manager()
result = manager.list() # 각 프로세스가 안전하게 수정할 수 있는 리스트
procs = []
for i in range(2):
# 프로세스 수만큼 코어 할당
p = multiprocessing.Process(target=work, args=(i, START, END, result))
p.start()
procs.append(p)
print(f'{i+1} 번째 실행')
for p in procs:
p.join() # 프로세스가 모두 종료될 때까지 대기
time_elapsed2 = round(time.time() - start, 2)
speed_up = round(time_elapsed1/time_elapsed2, 1)
print(time_elapsed2, ' 초 경과')
print(speed_up, ' 배 속도 향상')
print(f"합계 결과: {sum(result)}")
# 1 번째 실행
# 2 번째 실행
# 5.47 초 경과
# 1.7 배 속도 향상
# 합계 결과: 2499999950000000
시스템 명령어 실행
subprocess
- subprocess는 파이썬 스크립트 상에서 외부 프로세스 시스템 명령어를 실행할 때 사용하는 표준 모듈
- 새로운 프로세스를 실행하도록 도와주며, 프로세서의 입/출력 및 에러 결과에 대한 리턴 값을 사용자가 직접 제어할 수 있게 도와줌
import subprocess
subprocess.run(['python', 'test.py'])
출력된 결과를 txt 파일로 저장
f = open('output.txt', 'w')
out = subprocess.checkout(['python', 'test.py'], encoding='utf-8')
f.write(out)
f.close()
'Python > 학습용' 카테고리의 다른 글
데이터 베이스 만들기 (0) | 2025.02.23 |
---|---|
N배 빠른 크롤링(3) (0) | 2025.02.23 |
N배 빠른 크롤링(1) (0) | 2025.02.23 |
[ML] 비지도학습 (0) | 2025.01.29 |
Python-SQL 연결(데이터 추출) (0) | 2025.01.25 |