프로세스
프로그램이 실행되기 위해 주메모리에 올라와 있는 동적 상태, 단순히 실행 중인 프로그램으로 생각하면 편하다
스레드
스레드란 프로세스 내에서 실행되는 여러 작업의 단위, 스레드가 한개로 동작하면 싱글, 여러 개의 스레드가 동작하면 멀티 스레딩
- 멀티 스레드끼리 메모리 공유와 통신 가능
- 자원 낭비 막고 효율성 향상
- 한 스레드에 문제가 생기면 전체 프로세스에 영향을 미친다
동시성 (Concurrency): 한번에 여러 작업을 동시에 다루는 것을 의미 한 가지 일을 스위칭 해가면서 여러 작업을 동시에 수행
병렬성 (Parallelism): 한번에 여러 작업을 병렬적으로 처리하는 것을 의미 at the same time
아래 코드는 파이썬 멀티 쓰레딩 코드이다. 참고로 파이썬에서 멀티 스레딩은 병렬적으로 수행되지 않는다.
스레드를 만들고 우선순위를 만드는 것도 시간이 걸린다 차라리 코루틴으로 작성하는 것 추천
import requests
import time
import os
import threading
from concurrent.futures import ThreadPoolExecutor
# fetcher 함수가 어떤 프로세스에서 어떤 쓰레드로 작동하는 지 알아보자
def fetcher(params):
session = params[0]
url = params[1]
#os.getpid : 현재 프로세스의 id를 리턴, 프로세스는 각각의 i가 존재
# threading.get_ident: 현재 쓰레드의 ident를 리턴
print(f"{os.getpid()} process | {threading.get_ident()} url : {url}")
with session.get(url) as response:
return response.text
def main():
urls = ["https://google.com","https://apple.com"]*50
#max_workers: 최대 스레드를 실행할 갯수
executor = ThreadPoolExecutor(max_workers = 10)
with requests.Session() as session:
params = [(session,url) for url in urls]
result = list(executor.map(fetcher,params))
if __name__ == "__main__":
start = time.time()
main()
end = time.time()
print(f"소요시간: {end- start} 초") #10.17
93924 process | 6202077184 url : https://apple.com
93924 process | 6252556288 url : https://google.com
.
.
.
93924 process | 6218903552 url : https://google.com
93924 process | 6286209024 url : https://apple.com
소요시간: 2.0476222038269043 초
멀티스레딩은 메모리를 공유한다. 계산하다가 한 스레드에서 에러가 발생한다면 다른 스레드에도 영향을 미쳐 충돌이 발생할 수 있다. 이러한 문제점을 막기 위한 것이 GIL이다.
- GIL은 본질적으로 한 스레드가 다른 스레드를 차단해서 제어를 얻는 것을 막아준다. 이때문에 파이썬은 멀티 스레드로 병렬 연산을 수행하지 못함