[threading - Thread-based parallelism]
■ Lock Objects
primitive lock 은 잠긴 상태일때 특정 thread 가 소유할 수 없는 동기화 primitive 이다. 현재 파이썬에서 _thread 확장 모듈에 의해 직접 구현되는 가장 low 한 동기화 primitive 이다. primitive lock은 locked 와 unlocke, 두가지 상태를 가지고 있는데, 초기 생성 시에는 unlocked 상태로 생성된다. 해당 class 는 acquire 와 release, 두개의 메소드를 가지고 있으며, 이를 통해서 Lock 의 상태를 다룰 수 있다. 각 메소드는 현재 lock 의 상태가 locked 인지 unlocked 인지에 따라서 다르게 작동한다.
- acquire
• locked 상태인 경우, 다른 thread 에서 release() 호출을 통해서 lock 을 unlocked 상태로 바꿀 때까지 block 된다. lock 이 unlocked 상태로 바뀌는 경우 해당 thread 에서 loop 를 획득하여 locked 상태로 바꾸고 이를 반환한다.
• unlocked 상태인 경우, lock을 locked 상태로 바꾸고 반환한다.
- release
• locked 상태인 경우, lock을 unlocked 상태로 변환한다.
• unlocked 상태인 경우, RuntimeError 가 발생한다.
두개 이상의 thread가 lock 이 잠김 상태에서 acquire 를 호출하여 대기 상태인 경우, release 를 호출하여서 lock 이 초기화 된 후 하나의 thread 만이 실행된다. 어떤 thread 가 상태가 변경되는 지는 구현에 따라서 달리질 수 있다.
■ threading.Lock
primitive Lock 객체를 구현하는 class 이다. 한번 lock 을 획득하면 이후의 acquire 는 lock 이 release 될 때까지 block 된다. 모든 thread 가 release 를 호출할 수 있다. Lock 은 해당 플랫폼 지원하는 가장 효율적인 Lock class instance 를 반환하는 factory function 이다.
- acquire(blocking=True, timeout=-1)
• acquire 메소드를 호출한 thread 에서 lock 을 획득한다.
• blocking 인자를 True 로 한 경우, lock 이 unlocked 상태가 될 때까지 block 된 상태로 대기하다가 unlocked 된 lock 을 획득하여 다시 locked 상태로 바꾸고 True 를 반환한다.
• blocking 인자를 False 로 한 경우, block 되지 않는다. lock 이 locked 상태인 경우 바로 False 를 반환한다. unlocked 상태인 경우 lock 을 획득하여 locked 상태로 바꾸고 True 를 반환한다.
• timeout 인자에 주어진 시간만큼 block 된 상태로 대기한다. 만약 -1 이 주어진 경우 제한없이 대기하도록 한다.
• blocking 인자가 False 인 경우 timeout 을 설정할 수 없다.
- release()
• lock 을 release 한다.
• 해당 method 는 lock 을 가지고 있는 thread 뿐만 아니라 모든 thread 에서 호출할 수 있다.
• locked 상태의 lock 을 unlocked 상태로 변경하고 반환한다. 다른 thread 들에서 lock 을 갖기 위해서 block 된 상태인 경우 해당 thread 들 중 하나가 실행되도록 한다.
• lock 이 unlocked 상태에서 release 를 호출한 경우 Runtime Error 가 발생한다.
- locked()
• lock 이 locked 상태인지 아닌지를 반환한다.
■ RLock Object
RLock (reentrant lock) 은 같은 thread 에 대해서 lock 을 여러번 획득할 수 있는 동기화 primitive 이다. RLock 은 primitive lock 의 locked/unlocked 상태 개념에 더해 owning thread, recursion level 개념을 사용한다. locked 상태에서는 특정 thread 가 lock 을 소유하고, unklocked 상태에서는 아무도 소유하지 않는다. lock 을 다루기 위해서 호출된 acquire 와 release 메소드 쌍이 중첩 될 수 있는데, 이때 마지막 release 메소드가 lock 을 unlocked 상태로 변환하고 다른 thread 가 실행될 수 있도록 초기화한다.
■ threading.RLock
reentrant lock object 를 구현하는 class 이다. reentrant lock 은 lock 을 획득한 thread 에서만 lock 을 release 해야한다. 한번 RLock 을 획득하면 같은 thread 에서는 block 없이 다시 RLock 을 획득할 수 있다.
- acquire(blocking=True, timeout=-1)
• lock 을 획득한다.
• 만약 이미 lock 을 소유하고 있는 thread 에서 호출한 경우 recursion level 을 하나 증가시킨다.
• 만약 lock 을 다른 thread 에서 소유하고 있는 경우, unlocked 될 때까지 block 된다.
• unlocked 된 lock 을 획득하는 경우, recursion level 을 1로 설정한다.
- release()
• recursioin level 을 감소시키면서 lock 을 해제한다.
• 만약 감소된 recursion level 이 0인 경우 lock 을 unlocked 상태로 초기화한다.
• 만약 lock 을 소유하고 있지 않은 thread 에서 release 한 경우 RuntimeError 가 발생한다.
<reference>
- Python Documentation >> The Python Standard Library >> Concurrent Execution
'프로그래밍언어 > Python' 카테고리의 다른 글
[Python] urlparse (0) | 2021.10.16 |
---|---|
[Python] argparser (0) | 2021.09.11 |
[Python] Python 병렬처리 - threading (2) (0) | 2021.04.25 |
[Python] Python 병렬처리 - threading (1) (1) | 2021.04.25 |
[Python] Asterisks(*) in Python (2) | 2021.04.14 |