Queue를 사용하다보면 Thread간 Queue를 공유하다보니 특정 Thread별로 Queue를 지정하여 마치 채널처럼 사용하고 싶은 경우가 발생하게 됩니다.

이 경우를 해결하고자 두 가지 방법은 고안해내었습니다.

 

1. Thread 생성시 Thread별로 Queue를 별도의 변수담아 구분하여 인자로 넘겨주는 방법

  • 1번,2번 Thread는 queue1이라는 변수에 큐를 담아 사용,
  • 3번,4,번 Thread는 queue2라는 변수에 큐를 담아 사용

2. globals() 함수와 heapq 모듈을 이용하여 전역변수로 데이터를 전송하는 방법으로 원하는 데이터만 골라서 출력이 가능하다.

 

 

 

[첫번째 방법]

from queue import Queue
import threading
import time



def thread1_push(q):
    q.put('Thread1 Push Zero')
    q.put('Thread1 Push One')
    q.put('Thread1 Push Two')
    q.put('Thread1 Push Three')
    q.put('Thread1 Push Four')


def thread3_push(q):
    q.put('Thread3 Push Zero')
    q.put('Thread3 Push One')
    q.put('Thread3 Push Two')
    q.put('Thread3 Push Three')
    q.put('Thread3 Push Four')


def thread2_pop(q):
    while True:
        pop = q.get()  # 큐의 내용을 얻어옮
        if pop:
            time.sleep(1.1)
            print('Thread2 : ' + str(pop))


def thread4_pop(q):
    while True:
        pop = q.get()  # 큐의 내용을 얻어옮
        if pop:
            time.sleep(1.5)
            print('Thread4 : ' + str(pop))

if __name__ == "__main__":
    queue1 = Queue()  # 큐 생성
    queue2 = Queue()  # 큐 생성
    thread1 = threading.Thread(target=thread1_push, args=(queue1, ))
    thread2 = threading.Thread(target=thread2_pop, args=(queue1, ))
    thread3 = threading.Thread(target=thread3_push, args=(queue2, ))
    thread4 = threading.Thread(target=thread4_pop, args=(queue2, ))
    thread1.start()
    thread2.start()
    thread3.start()
    thread4.start()

 

[첫번째 방법 실행결과]

 

 

 

 

 

 

 

 

 

 

 

 

2번은 1번 thread의 내용을 4번은 3번 thread의 내용을 출력하는 것을 확인 할 수 있습니다.

 

 

[두번째 방법]

# -*- coding:utf-8 -*-

import heapq
import threading
import time
#글로벌 변수 선언
def glname():
    for i in range(0, 5):
        name = 'task_' + str(i)  # task_0,1,3,4 선언될 글로벌 변수명
        globals()[name] = []


#해당 글로벌변수로 push
def thread1_push():
    heapq.heappush(task_0, "Thread1 Zero")
    heapq.heappush(task_1, "Thread1 One")
    heapq.heappush(task_2, "Thread1 Two")
    heapq.heappush(task_3, "Thread1 Three")
    heapq.heappush(task_4, "Thread1 Four")


def thread2_push():
    heapq.heappush(task_0, "Thread2 Zero")
    heapq.heappush(task_1, "Thread2 One")
    heapq.heappush(task_2, "Thread2 Two")
    heapq.heappush(task_3, "Thread2 Three")
    heapq.heappush(task_4, "Thread2 Four")


#선택적 출력
def pop():
    while True:
        try:
            pop0 = heapq.heappop(task_0)
            pop1 = heapq.heappop(task_1)

            print(pop0)
            time.sleep(1)
            print(pop1)
            time.sleep(1)
        except:
            pass


if __name__ == "__main__":
    glname()
    thread1 = threading.Thread(target=thread1_push, args=())
    thread2 = threading.Thread(target=thread2_push, args=())
    thread3 = threading.Thread(target=pop, args=())
    thread1.start()
    thread2.start()
    thread3.start()

 

[두번째 방법 실행결과]

일반 Queue의 경우 별도의 queue 변수에 담아서 thread실행시 인자로 넘겨주어야 하지만 heapq와 globals() 함수를 이용하면 하나의 Thread에서 글로벌 변수로 선언된 여러개의 Queue를 사용할 수 있습니다.

+ Recent posts