- 병렬 처리는 Multiprocessing, asyncio 선택지 다양
- thread 동시성 완벽 처리를 위해 Jython, IronPython, Stackless Python 등이 존재
thread 기초
join
사용
- Main-Thread가 Sub-Thread종료 기다림
DaemonThread
- DaemonThread
- 백그라운드에 실행
- 메인스레드 종료시 즉시 종료
- 주로 백그라운드 무한 대기 이벤트 발생 실행하는 부분 담당
class 상속 받아 사용하기
import threading
import subprocess
class AppRunner(threading.Thread):
def __init__(self, cmd: str):
threading.Thread.__init__(self)
self.cmd=cmd
def run(self):
print(self.cmd)
self.proc=subprocess.Popen(slef.cmd, shell=True, executable='/bin/bash', \
stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
try:
out, err = self.proc.communicate()
except: subprocess.TimeoutExpired:
print("[ERROR]: rsync timeout expired")
else:
if out != '':
print(out)
if __name__=='__main__':
rsync_cmd="rsync -aq $HOME/ffmpeg/ $HOME/dummy"
rsync1=AppRunner(rsync_cmd)
rsync1.start()
rsync1.join()
if rsync1.proc.returncode == 0:
print("[INFO]: {:s} return {}".format(rsync1.cmd, rsync1.proc.returncode)
else:
print("[ERROR]: {:s} return {}".format(rsync1.cmd, rsync1.proc.returncode)
ThreadPoolExecutor
- 그룹스레드
- Python 3.2 이상
concurrent.futures
with
사용으로 생성, 소멸 라이프사이클 관리 용이
- 디버깅 난해(단점)
- 대기 중인 작업 -> Queue -> 완료 상태 조사 -> 결과 또는 예외 -> 단일화(캡슐)
기초
with
사용
Lock, Deadlock
- Lock: 상호 배제를 위한 잠금(Lock) 상태: 데이터 경쟁
- Deadlock: 프로세스가 자원을 획득하지 못해 다음 처리를 못하는 무한 대기 상황(교착 상태)
- Lock이 필요한 이유를 보자.
- 이 경우 3이 되어야 하는데, 2가 나온다.
threading.Lock(), acquire(), release()
with文 사용
Prod and Cons Using Queue
- Python Event 객체
- Flag 초기값 0
- Set() -> 1
- Clear() -> 0
- Wait() 1->리턴, 0->대기
- isSet() -> 현 플래그 상태
multiprocessing
terminate(): 프로세스 강제종료
예제
ProcessPoolExecutor