2019. 8. 11. 15:00ㆍ분석 Python/구현 및 자료
https://data-newbie.tistory.com/229
앞에서는 threading과 동기화에 대해서 써봤다.
이번에는 queue를 사용해서 스레드 간 데이터 전달 과정
먼가 이 producer와 consumer를 보면 kafka가 생각난다. 먼가 같은 방식인 것 같기도 한데...
import threading
from queue import Queue
def creator(data, q):
"""
생산자 : 쓰레드간 데이터 전송 예제
"""
print('Creating data and putting it on the queue')
print('\n')
for item in data:
evt = threading.Event()
q.put((item, evt))
print('Waiting for data to be doubled')
evt.wait()
def consumer(q):
"""
소비자 : 쓰레드간 데이터 전송 예제
"""
while True:
data, evt = q.get()
print('Receive Original Data : {}'.format(data))
processed = data * 5
print('Receive Processed Data : {}'.format(processed))
print('\n')
evt.set()
q.task_done()
if __name__ == '__main__':
q = Queue()
data = [7, 14, 39, 59, 77, 1, 109, 99, 167, 920, 1035]
thread_one = threading.Thread(target=creator, args=(data, q))
thread_two = threading.Thread(target=consumer, args=(q,))
thread_one.start()
thread_two.start()
q.join()
진행은 creator 가 모든 데이터를 소비한 후에 (q에 저장한 후에) consumer가 이를 이용한다는 것을 알 수 있습니다.
import threading
import queue
from time import sleep
def myThread(name,q):
i = 0
while True:
sleep(1)
q.put(i)
i +=1
if __name__ == '__main__' :
BUF_SIZE = 10
q = queue.Queue(BUF_SIZE)
t = threading.Thread(target=myThread, args=("Thread-1", q))
t.start()
print("queue에 쌓기 완료?")
while True:
num = q.get()
print (str(num) + " 이 생성되었습니다")
print ("---- exit ----")
import threading
import time
class Worker(threading.Thread):
"""클래스 생성시 threading.Thread를 상속받아 만들면 된다"""
def __init__(self, args, name=""):
"""__init__ 메소드 안에서 threading.Thread를 init한다"""
threading.Thread.__init__(self)
self.name = name
self.args = args
def run(self):
"""start()시 실제로 실행되는 부분이다"""
print("{} is start : {}".format(threading.currentThread().getName(), self.args[0]))
time.sleep(5)
print("{} is end".format(threading.currentThread().getName()))
def main():
for i in range(10):
# threading.Thread 대신, 클래스명으로 쓰레드 객체를 생성하면 된다
msg = "hello"
th = Worker(name="[th cls {}]".format(i), args=(msg,))
th.start() # run()에 구현한 부분이 실행된다
if __name__ == "__main__":
main()
데몬(Daemon) 쓰레드
스레드를 데몬으로 만들어서 사용할 수 있다.
주요 작업을 하는 메인 스레드는 따로 있고, 백그라운드 작업을 위한 스레드를 띄울 수 있다는 것
이러한 백그라운드 작업을 데몬으로 띄우지 않으면, 백그라운드 작업을 하는 스레드가 종료될 때까지 메인 프로그램도 종료되지 않는다.
> 위의 표현이 내가 지금 하고자 하는 것에 가장 잘 맞는 것 같다.
> 어떤 큰 메인은 있는 상태에서 여러 모델들은 계속 띄워놓고 있는 상황
> 큰 메인에서는 저 여러 개를 띄워 놓는 것을 바꿀 수 있게?
프로그램의 상태를 모니터링하는 프로그램이 내부에서 주기적으로 동작하는데,
만약 이 프로그램 때문에 메인 프로그램이 종료되지 못하면 이상하다.
데몬 스레드는 메인 프로그램이 종료될 때 자동으로 같이 종료된다.
즉, 정기적이고 부수적인 작업은 데몬으로, 필수적인 메인 작업은 일반 스레드로 띄운다
스레드가 시작하고 종료되지 않은 예
메인 프로그램이 종료되면서 데몬 쓰레들이 자동으로 같이 종료되었기 때문.
import threading
import time
def worker(msg):
print("{} is start : {}".format(threading.currentThread().getName(), msg))
time.sleep(5)
print("{} is end".format(threading.currentThread().getName()))
def main():
msg = "hello"
th = threading.Thread(target=worker, name="[Daemon]", args=(msg,))
th.setDaemon(True)
th.start()
print("Main Thread End")
if __name__ == "__main__":
main()
메인 프로그램이 데몬 스레드가 끝날 때까지 기다리도록 하기 (join)
def worker(msg):
print("{} is start : {}".format(threading.currentThread().getName(), msg))
time.sleep(5)
print("{} is end".format(threading.currentThread().getName()))
def main():
msg = "hello"
th = threading.Thread(target=worker, name="[Daemon]", args=(msg,))
th.setDaemon(True)
th.start()
th.join()
print("Main Thread End")
if __name__ == "__main__":
main()
join 부분에서 데몬스레드가 종료될때까지 기다렸다가 메인 쓰레드가 수행된 것 확인
https://niceman.tistory.com/140?category=940952
'분석 Python > 구현 및 자료' 카테고리의 다른 글
[ Python ] threading 에 대해서 잘 설명된 글 (0) | 2019.08.11 |
---|---|
[ Python ] 동시성과 Future / concurrent.futures 알아보기 (0) | 2019.08.11 |
[ Python ] thread 공부해보기-1 (2) | 2019.08.11 |
[ Python ] combination 조합 만들기 (0) | 2019.07.24 |
[ Python ] Regex 유용한 팁들! (0) | 2019.07.20 |