티스토리 뷰

Python

Python,module queue

hwangyoungjae 2016. 5. 20. 21:52
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

컴퓨터분야에서 널리 이용되는 자료구조로 스택(stack), queue)가 있다스택과 큐는 프로그래밍할때 기본이 되는 자료구조로 이를 이용하여 함수파라미터 전달메시지 큐 등으로 다양하게 확장할수 있다.

 

파이썬에서는 queue모듈에서 큐(Queue), 우선순위큐(PriorityQueue), 스택(LifoQueue)을 제공하고 있다특히 큐 모듈은 스레드환경을 고려하여 작성되었기에여러 스레드들을 동시에 큐객체(queue모듈에서 제공되는 3개의 클래스를 지칭)에 데이터를 입력하고데이터를 출력하여도 정상적으로 작동하는것을 보장한다.

 

queue모듈에 정의되어 있는 클래스는 아래와 같다클래스 생성시 인자로 전달되는 maxsize는 해당클래스가 저장할두 있는 최대 아이템개수이다명시적으로 아이템의 갯수를 지정하지 않거나 0보다 같거나 작은겨ㅇ우저장할수 있는 큐의 크기는 메모리가 수용하는한 무한히 늘어날수 있다.

클래스

내용

queue.Queue(maxsize)

선입선출(FIFO First-In, First-Out)큐 객체를 생성

queue.LifoQueue(maxsize)

일반적으로 스택(Stack)이라 불리는 후입선출(LIFO Last-In, First-Out)큐 객체를 생성

queue.PriorityQueue(maxsize)

우선순위 큐 객체를 생성

입력되는 아이템의 형식은 (순위아이템)의 튜플로 입력되며,

우선순위는 숫자가 작을수록 높은 순위를 갖는다.

 

위으 3개의 클래스는 아래표에 있는 메서드를 동일하게 가지고 있다각 메서드의 의미는 동일하지만해당 클래스의 정렬방식에 따라서 GET계열 메서드의 결과가 달라진다.

메서드

내용

qsize()

큐 객체에 입력된 아이템의 개수를 반환

put(item[, block[, timeout]])

큐 객체에 아이템을 입력한다.

put_nowait(item)

블로킹(blocking)없이 큐 객체에 아이템을 입력한다.

큐 객체가 꽉 차 있는 경우에는 queue.Full예외 발생

get([block[, timeout]])

생성된 큐 객체 특성에 맞추어아이템 1개를 반환

get_nowait()

블로킹(blocking)없이 큐 객체에 들어있는 아이템을 반환

큐 객체에 아이템이 없는 경우에는 queue.Empty 예외 발생

 

아래의 예외는 큐객체의 크기와 관련하여 발생할수 있는 예외이다.

예외

내용

queue.Empty

큐 객체에 아이템이 없는 경우 발생

queue.Full

큐 객체에 아이템이 꽉 찬 경우에 발생

 

>> 기본동작 <<

위에서 설명한 3개의 큐 객체는 아이템을 입력하고출력하는 동작방법이 모두 동일하다.

아래 예제에서는 큐 객체를 이용하여 데이터를 입력출력하는 방법을 알아보도록 하겠다.

>>> import queue

>>> q=queue.Queue()

>>> q.put('apple'#큐 객체에 데이터 입력

>>> q.put('banana')

>>> q.put(10)

>>> q.qsize() #큐 객체에 저장된 데이터 갯수

3

>>> q.get() #큐 객체에서 데이터 출력

'apple'

>>> q.get()

'banana'

>>> q.qsize() #2개 출력후 저장된 데이터 갯수

1

 

>> Queue, LifoQueue, PriorityQueue클래스의 특성 <<

Queue, LifoQueue, PriorityQueue객체 입력 방법은 모두 동일하지만 내부 정렬방식이 다르기 때문에 출력시 순서가 다르다.

출력방법이 변경되는 것을 확인하기 위하여 아래와 같은 함수를 하나 정의하였다.

아래의 함수는 queue에 정이된 클래스를 받아서 모든 데이터를get()하여 리스트로 반환하는 함수이다.

입력시 데이터가의 순서가 동일하도록 입력한뒤함수 결과로 반환된 리스트를 비교하여 각 객체의 정렬방식을 비교해보도록 하겠다.

ex)큐객체의데이터출력용함수(GetItemList())

def GetItemList(q):

    ret=[]

    n=q.qsize()

    while n > 0:

        ret.append(q.get())

        n -= 1

    return ret

 

Queue객체는 먼저 입력된 데이터가 먼저 출력되는 구조이다.

이러한 구조를 선입선출(FIFO : First-In, First-Out)구조라 한다.

>>> l='apple,banana,orange'

>>> q=queue.Queue()

>>> for x in l.split(','):

             q.put(x)

 

>>> GetItemList(q)

['apple', 'banana', 'orange']

 

반면에 LifoQueue객체는 나중에 입력된 데이터가 먼저 출력되는 구조이다.

이러한 구조를 후입선출(LIFO : Last-In, First-Out)구조라 한다.

>>> q=queue.LifoQueue()

>>> for x in l.split(','):

             q.put(x)

 

>>> GetItemList(q)

['orange', 'banana', 'apple']

 

PriorityQueue는 입력되는 순서와 상관없이 데이터자체에 우선순위에 대한 정보를 가지고 있다그렇기에 입력시우선순위에 대한 정보를(순위아이템)의 튜플형태로 입력해야 한다또한 데이터의 출력 순서는 입력된 아이템의 순위가 높은 순서대로 출력된다.

숫자가 낮을수록 높은 순위를 나타낸다.

>>> q=queue.PriorityQueue()

>>> q.put((5,'apple'))

>>> q.put((10,'banana'))

>>> q.put((1,'orange'))

>>> GetItemList(q) #인자로 전달된 우선순위대로 출력

[(1, 'orange'), (5, 'apple'), (10, 'banana')]

 

>> pyt_nowait() get_nowait()메서드 <<

큐 객체 생성시 저장할수 있는 아이템 크기를 명시적으로 지정할수 있다.

이러한 경우 큐 객체에 저장된 아이템이 없는 상태에서 get()이 호출되거나반대로 아이템이 저장할수 있는 사이즈를 꽉 채운상태에서 put()이 호출되는 경우큐 객체는 블록킹(Blocking)된다.

아래의 예제를 IDLE에서 수행하면 커서만 깜박거리고 어떠한 동작도 수행하지 않는것을 확인할수 있다.

>>> import queue

>>> q=queue.Queue(2) #아이템이 2개만 저장가능하도록 설정

>>> q.put('a')

>>> q.put('b') #큐의 저장 한계

>>> q.put('c'#다른 스레드가 아이템을 가지고 갈때까지 무한 대기

 

이렇게 무한대기하는 상태를 피하고자 put_nowait() get_nowait()메서드를 지원한다.

이 두 메서드는 큐 객체의 상태에 상관없이 블록킹되지 않고 즉시 결과를 반환한다.

대신 큐 객체가 꽉 찬 경우에는 queue.Full예외를,

큐 객체가 빈 경우에는 queue.Empty예외를 발생하기 때문에

프로그래머는 해당상태에 맞추어서 적절한 처리를 할수 있다.

>>> import queue

>>> q=queue.Queue(2)

>>> q.put_nowait('a')

>>> q.put_nowait('b')

>>> q.put_nowait('c'#큐 객체가 꽉찬 경우

Traceback (most recent call last):

  File "<pyshell#9>", line 1, in <module>

    q.put_nowait('c')

queue.Full

>>> q.get_nowait()

'a'

>>> q.get_nowait()

'b'

>>> q.get_nowait() #큐 객체가 빈 경우

Traceback (most recent call last):

  File "<pyshell#12>", line 1, in <module>

    q.get_nowait()

queue.Empty

 

또한 put(), get()메서드에도 추가적인 인자를 전달하여 더 다양한 동작을 수행할수 있다아래의 메서드 원형에서 <block>은 블로킹 유무를, <timeout>은 블로킹이 될 시간을 초단위로 입력할수 있다.

put(item[, block[, timeout]])

get([block[, timeout]])

아래의 코드는 큐 객체가 꽉 찬 경우 5초간 다른 스레드가 아이템을 출력하기를 기다리며 블록킹 되었다가 시간디 지나면 queue.Full예외를 발생시키는 예제이다.

>>> import queue

>>> q=queue.Queue(2)

>>> q.put('a')

>>> q.put('b'#큐 객체가 꽉 참

>>> q.put('c',True,5) #5초동안 대기후 블록킹됨

Traceback (most recent call last):

  File "<pyshell#18>", line 1, in <module>

    q.put('c',True,5)

queue.Full

 

put()메서드를 아래와 같이 호출하면 put_nowait()과 동일한 동작을 수행함

>>> q.put('c',False)

Traceback (most recent call last):

  File "<pyshell#20>", line 1, in <module>

    q.put('c',False)

queue.Full

 

 

참조 : 빠르게 활용하는 파이썬프로그래밍

'Python' 카테고리의 다른 글

Python, XML사용하기  (0) 2016.05.20
Python,module weakref [약한참조]  (0) 2016.05.20
Python,module threading [멀티스레드]  (0) 2016.05.19
Python, 데이터베이스의 사용  (0) 2016.05.19
Python,module random [랜덤]  (0) 2016.05.19
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/07   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31
글 보관함