[ Python ] thread 공부해보기-2

2019. 8. 11. 15:00분석 Python/구현 및 자료

728x90

https://data-newbie.tistory.com/229

 

Python thread 공부해보기-1

최근에 머 하나를 병렬적으로 실행하고 싶은게 있었다. 그래서 멀티프로세싱으로 하려고 시도를 했는데, 동작하지 않아서 threading을 활용해서 thread 형식으로 했다. 하지만 내가 알기론 GIL? 이것 때문에 threa..

data-newbie.tistory.com

 

앞에서는 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) - Thread(쓰레드) 설명 및 예제 소스 코드(3) - 데이터 통신

파이썬(Python) Thread - 데이터 전달 설명 지난 시간에 이어서 오늘은 파이썬 쓰레드 동기화 및 데이터 전달에 대해서 간단하게 설명하겠습니다. 쓰레드 작업에서 메시지 전달 기능 추가는 각 쓰레드 간에 동기화..

niceman.tistory.com

 

728x90