패스트 캠퍼스에 컴퓨터 공학 강의를 정리한 내용이다.
2. 쓰레드의 장단점
쓰레드의 장점
- 사용자에 대한 응답성 향상
- 자원 공유 효율이 높다.
- 한 프로세스에서 자원을 공유하므로 IPC보다 자원 공유 효율이 좋다.
- 프로세스를 복사하고 통신하는 형태가 아니라 저장공간 관리 효율이 좋다.
- 쓰레드에 정의로 코드가 간결해 진다.
쓰레드의 단점
- 스레드 중 한 스레드만 문제가 있어도, 전체 프로세스가 영향을 받음.
- 스레드를 많이 생성하면, Context Switching이 많이 일어나, 성능 저하
3. 쓰레드의 동기화 문제
동기화 ?
- 작업들 사이에 실행 시기를 맞추는 것
- 여러 스레드가 종일한 자원(데이터) 접근시 동기화 이슈 발생
- 여러 쓰레드 1, 2가 있을 때 쓰레드1 에서 연산을 수행하고 변수에 저장하기 전에 컨텍스트 스위칭이 발생하면 쓰레드 2에서는 저장되기 전에 변수 값을 받아서 연산을 수행하므로 동기화 이슈가 생김
python에서 쓰레드
# 쓰레드 모듈 임포트
import threading
# 글로벌 변수에다가 10000까지 각 스레에서 더한값을 더함.
total = 0
def sum():
global total
for i in range(10000):
total += 1
thread_list = []
for i in range(50):
t = threading.Thread(target = sum)
thread_list.append(t)
for th in thread_list:
th.start()
for th in thread_list:
th.join()
print(total)
스레드를 실행해서 각각 스레드에서 10000씩 더 한 것을 합쳐서 빠르게 total을 구할 수 있다.
- 10000이 아니라 50000000이라면??
- 컨텍스트 스위칭이 변수를 저장하기 전에 일어나면서 값도 다르고 실행할때마다 동일하지 않게 됨.
mutual_exclusion을 사용함
스레드에 락을 걸어서 실행이 끝날때 까지 다음 스레드는 접근을 못하게 함. 전 스레드가 락 걸린 부분에 코드를 모두 수행하면 키를 반환하고 다음 스레드에서 실행 가능.
→ 상호 배제 ( 공유 변수를 갱신할때 다른 쓰레드가 접근하지 못하게 함.)
lock = threading.Lock()
# 코드 실행되는 부분에서 추가
lock.acquire()
# 코드 끝나는 부분 추가(키 반환)
lock.release()
추가한 코드는 다음과 같다.
import threading
# 글로벌 변수에다가 10000까지 각 스레에서 더한값을 더함.
total = 0
def sum():
global total
lock.acquire()
for i in range(10000):
total += 1
lock.release()
lock = threading.Lock()
thread_list = []
for i in range(50):
t = threading.Thread(target = sum)
thread_list.append(t)
for th in thread_list:
th.start()
for th in thread_list:
th.join()
print(total)
댓글