본문 바로가기
파이썬

파이썬 Queue - a aynchronized queue class

by 혜룐 2015. 11. 10.
The Queue module implements multi-producer, multi-consumer queues. It is especially useful in threaded programming when information must be exchanged safely between multiple threads. The Queue class in this module implements all the required locking semantics.
Queue.put
item[, block[, timeout]]
put_nowait(item)
Queue.get
[block[, timeout]]
get_nowait()
Queue.task_done
Queue.join
Blocks until all items in the queue have been gotten and processed.
The count of unfinished tasks goes up whenever an item is added to the queue. The count goes down whenever a consumer thread calls task_done()to indicate that the item was retrieved and all work on it is complete. When the count of unfinished tasks drops to zero, join() unblocks.
큐 객체에 0~9까지 아이템을 put 하고, 큐 사이즈 만큼 get 하고, 큐 사이즈que.qsize() 와 반환되는 아이템 que.get() 을 확인 해 보자.
import Queue
que = Queue.Queue()
def workerQue():
for i in range(10):
que.put(i)
for i in range(que.qsize()):
print i, " th: ", que.qsize(), que.get()
#print 'first get : ', que.qsize(), que.get()
#print 'second get: ' que.qsize(), que.get()
workerQue()
LIFO
큐 객체와,
FIFO
큐 객체의 모습을 확인 해보자.
import Queue
que =
Queue.Queue()
lifoQue =
Queue.LifoQueue()
def workerQue():
for i in range(10):
que.put(i)
for i in range(que.qsize()):
print i, " th: ", que.qsize(), que.get()
workerQue()
print "==== queue.Queue vs queue.LifoQueue ===="
def workerLifoQue():
for i in range(10):
lifoQue.put(i)
for i in range(lifoQue.qsize()):
print i, " th: ", lifoQue.qsize(), lifoQue.get()
workerLifoQue()
get_nowait() 와 put_nowait(item) 의 특성을 알아보자.
이는 둘다, 블로킹 없이, 큐 객체에 아이템을 입력/추가 한다.
즉, 큐 객체 생성시, 저장할수 있는 아이템의 크기를 지정해 생성할수 있는데( = que = Queue.Queue(10) ), 이런 경우, 아이템이 찬경우 put 하게 되거나, 꺼낼 아이템이 없는 경우 get 하게 되면, 큐 객체는 블럭킹이 된다. 그런 경우, 위 메소드를 사용하면 큐 객체 상태 상관없이 블럭킹 되지 않고, 결과를 즉시 알 수 있다.
print " 9' th: ", que.qsize(), que.get()
처럼, 큐 객체에있는 아이템을 다꺼내고,
한번더 get 해보자.
그러면 블락킹 상태가 될것이다.
[root@imaster python]# cat testQueue.py
import Queue
que = Queue.Queue(10)
lifoQue = Queue.LifoQueue(10)
def workerQue():
for i in range(10):
que.put(i)
for i in range(que.qsize()):
print i, " th: ", que.qsize(), que.get()
print " 9' th: ", que.qsize(), que.get()
workerQue()
print "==== queue.Queue vs queue.LifoQueue ===="
def workerLifoQue():
for i in range(10):
lifoQue.put(i)
for i in range(lifoQue.qsize()):
print i, " th: ", lifoQue.qsize(), lifoQue.get()
print " 9' th: ", lifoQue.qsize(), lifoQue.get()
workerLifoQue()
실행해보면, 아래처럼 블로킹 상태로, 그대로 멈춰버린다.
[root@master python]# python testQueue.py
0 th: 10 0
1 th: 9 1
2 th: 8 2
3 th: 7 3
4 th: 6 4
5 th: 5 5
6 th: 4 6
7 th: 3 7
8 th: 2 8
9 th: 1 9
Terminated
put_nowait(), get_nowait()
메소드로 발생할수 있는
exception
까지 추가해보자.
[root@master python]# cat testQueue.py
import Queue
que = Queue.Queue(10)
lifoQue = Queue.LifoQueue(10)
def workerQue():
for i in range(10):
que.put_nowait(i)
for i in range(que.qsize()):
print i, " th: ", que.qsize(), que.get_nowait()
try:
print " 9' th: ", que.qsize(),
que.get_nowait()
except:
print "exception~"
workerQue()
print "==== queue.Queue vs queue.LifoQueue ===="
def workerLifoQue():
for i in range(10):
lifoQue.put_nowait(i)
for i in range(lifoQue.qsize()):
print i, " th: ", lifoQue.qsize(), lifoQue.get_nowait()
try:
print " 9' th: ", lifoQue.qsize(),
lifoQue.get_nowait()
except:
print "exception~"
workerLifoQue()
실행해보면,
[root@master python]# python testQueue.py
0 th: 10 0
1 th: 9 1
2 th: 8 2
3 th: 7 3
4 th: 6 4
5 th: 5 5
6 th: 4 6
7 th: 3 7
8 th: 2 8
9 th: 1 9
9' th: 0 exception~
==== queue.Queue vs queue.LifoQueue ====
0 th: 10 9
1 th: 9 8
2 th: 8 7
3 th: 7 6
4 th: 6 5
5 th: 5 4
6 th: 4 3
7 th: 3 2
8 th: 2 1
9 th: 1 0
9' th: 0 exception~