2019.08.23 장고에서 Lock을 사용하여 멀티 스레드의 경합 막기
Lock
- 멀티 스레드 방식에서 경합을 막는 가장 일반적인 방법
- 하나의 프로세스에서 2개 이상의 스레드가 동시에 수행되는 경우, 스레드간에 프로세스 공간의 메모리를 공유한다.
- 여러 스레드가 잠금없이 같은 객체를 수정하면 프로그램 자료 구조가 오염될 수 있다.(race condition)
- 그것을 방지하기 위해 lock을 이용한다.
Lock 객체
- Lock 객체는 locked와 unlocked 2가지의 상태를 가지며, acquire()와 release()의 2가지 함수만을 제공한다.
- unlocked 상태에서 acquire가 호출되면 locked 상태로 바뀌고, locked 상태에서 release가 호출되면 unlocked 상태로 바뀌게 된다.
- 락은 자물쇠처럼 이를 선점한 스레드가 락을 획득하면, 자물쇠가 잠긴다. 이후에 접근하는 스레드들은 락이 열릴 때까지 그 앞에서 멈춰기다렸다가, 락을 선점한 스레드가 락을 풀어주면 차례로 획득 해제를 반복하면서 순차적으로 처리하는 모양을 만들게 된다. 가장 명료한 비유는 칸이 하나 밖에 없는 화장실을 생각하면 된다.
파이썬 스레드
기본 사용 방향
conn = redis.StrictRedis(REDIS_SERVER_IP)
lock_id = '{}'.format(id)
lock = redis_lock.Lock(conn, lock_id, expire=5)
if lock.acquire(blocking=False):
try:
원하는 코드
finally:
lock.release()
else:
실패 했을 때 실행할 코드
- 해당 lock_id를 통해서 그 특정 것에 대해 lock을 걸게 되므로 lock_id는 하나의 개개인으로 존재하는 것이 좋다.
- 실패했을 때 어떤 것을 실행하면 좋을까?
- 실행하다가 실패하게 되면 그 전 것들을 다 되돌려주는 작업을 진행하거나 해야한다.