"프로그래밍 언어의 개념과 흐름에 대한 고찰 - 파이썬답게 코딩하기" 학습중...
동시성과 관련한 thread 기법에 대해 어렴풋이 알거나 몰랐던 내용들 몇가지 정리해봅니다.
## Thread Re-entrant Lock 사용법
# import time
# import logging
# import threading
#
# logging.basicConfig(level = logging.DEBUG, format = "(%(threadName)s) %(message)s")
#
# RESOURCE = 0
#
# def set_reverse(lock) :
# logging.debug("start batch")
# ## with 구문을 통해 context manager object 를 사용한다면 try ~ finally 구문을 사용하지 않고도 관리하기 좋은 코드를 작성할 수 있다.
# ## 보통이라면 try: lock finally: pass로 구현해야 할 것을 with 하나로 해결. 즉 file open동작에서 close 생략 가능한 것 처럼.
# with lock :
# logging.debug("grap lock")
# if RESOURCE == 0 :
# set_one(lock, True)
# else :
# set_zero(lock, True)
# logging.debug("reserved")
#
# def set_zero(lock, end = False) :
# logging.debug("start set zero")
# while True :
# with lock :
# logging.debug("grap lock and set RESOURCE to 0.")
# RESOURCE = 0
# time.sleep(0.5)
# time.sleep(1)
# if end :
# break
#
# def set_one(lock, end = False) :
# logging.debug("start set one")
# while True :
# with lock :
# logging.debug("grap lock and set RESOURCE to 1.")
# RESOURCE = 1
# time.sleep(0.5)
# time.sleep(1)
# if end :
# break
#
# def main() :
# lock = threading.RLock()
# zero = threading.Thread(target = set_zero, name = "zero", args = (lock,))
# zero.setDaemon(True)
# zero.start()
#
# one = threading.Thread(target = set_one, name = "one", args = (lock,))
# one.setDaemon(True)
# one.start()
#
# time.sleep(6)
#
# reverse = threading.Thread(target = set_reverse, name = "reverse", args = (lock,))
# reverse.start()
#
# if __name__ == "__main__" :
# main()
# (zero) start set zero
# (zero) grap lock and set RESOURCE to 0.
# (one) start set one
# (one) grap lock and set RESOURCE to 1.
# (zero) grap lock and set RESOURCE to 0.
# (one) grap lock and set RESOURCE to 1.
# (zero) grap lock and set RESOURCE to 0.
# (one) grap lock and set RESOURCE to 1.
# (zero) grap lock and set RESOURCE to 0.
# (one) grap lock and set RESOURCE to 1.
# (reverse) start batch
# (reverse) grap lock
# (reverse) start set one
# (reverse) grap lock and set RESOURCE to 1.
# (reverse) reserved
# (zero) grap lock and set RESOURCE to 0.
## Lock을 잡은 상태에서 다른 함수나 클래스를 호출할 때 다시 그 Lock을 잡아야 할 경우에 사용한다.
## RLock은 Lock에 비해 처리해야 하는 프로세스가 더 있기 때문에 성능면에서 조금 더 느리다.
## Thread Condition
## 스레드의 락과 이벤트를 섞은 듯한 기능. 이 기능 사용시 모든 스레드가 락을 잡은 것처럼 멈춤. notify받으면 다시 동작.
# import time
# import logging
# import threading
#
# logging.basicConfig(level = logging.DEBUG, format = "(%(threadName)s) %(message)s")
#
# def receiver(condition) :
# logging.debug("start receiver")
# with condition :
# logging.debug("waiting...")
# condition.wait()
# time.sleep(1)
# logging.debug("end")
#
# def sender(condition) : ## receiver들에게 noti를 주는 기능
# logging.debug("start sender")
# with condition :
# logging.debug("send notify")
# condition.notifyAll()
# logging.debug("end")
#
# def main() :
# condition = threading.Condition() ## 스레드 5개 실행
# for i in range(5) :
# t = threading.Thread(target = receiver, name = "receiver %s" %i, args = (condition,))
# t.start()
#
# send = threading.Thread(target = sender, name = "sender", args = (condition,))
# time.sleep(1)
# with condition :
# condition.notify(1)
#
# time.sleep(3)
# send.start()
#
# if __name__ == "__main__" :
# main()
# (receiver 0) start receiver
# (receiver 0) waiting...
# (receiver 1) start receiver
# (receiver 2) start receiver
# (receiver 1) waiting...
# (receiver 3) start receiver
# (receiver 4) start receiver
# (receiver 2) waiting...
# (receiver 3) waiting...
# (receiver 4) waiting...
# (receiver 0) end
# (sender) start sender
# (sender) send notify
# (sender) end
# (receiver 1) end
# (receiver 3) end
# (receiver 4) end
# (receiver 2) end
'파이썬(PYTHON)' 카테고리의 다른 글
파이썬의 멀티프로세스(multiprocessing)1 (0) | 2020.08.28 |
---|---|
파이썬의 스레드(thread)4 (0) | 2020.08.27 |
파이썬의 스레드(thread)2 (0) | 2020.08.25 |
파이썬의 스레드(thread)1 (0) | 2020.08.24 |
파이썬의 기본 문법3 (0) | 2020.08.23 |