ใน Python การนำ stack และ queue data structures ไปใช้งานเป็นเรื่องง่าย Stack เรียกว่า LIFO เพราะทำงานหลักการ "Last-in, first-out" และ Queue เรียกว่า FIFO เพราะทำงานหลักการ "First-in, first-out" ฟังก์ชัน built-in ใน Python ทำให้โค้ดสั้นและง่าย
โมดูล Queue นำ multi-producer, multi-consumer queues ไปใช้งาน และมีประโยชน์โดยเฉพาะใน threaded programming เมื่อข้อมูลต้องแลกเปลี่ยนอย่างปลอดภัยระหว่างหลาย threads คลาส Queue ในโมดูลนี้นำ locking semantics ที่จำเป็นทั้งหมดไปใช้ และขึ้นอยู่กับความพร้อมของ thread support ใน Python
โมดูลนี้ implement สามประเภทของ queue ซึ่งแตกต่างกันเพียงแค่ลำดับที่ entries ถูกดึงออกมา สำหรับ FIFO queue งานแรกที่เพิ่มเข้ามาจะถูกดึงออกมาก่อน สำหรับ LIFO queue รายการที่เพิ่มล่าสุดจะถูกดึงออกมาก่อน (ทำงานคล้าย stack) และสำหรับ priority queue รายการถูกเก็บไว้เรียงลำดับ (ใช้ heapq module) และรายการที่มีค่าต่ำสุดจะถูกดึงออกมาก่อน
โมดูล queue นิยามคลาสและข้อยกเว้นดังนี้:
class Queue.Queue(maxsize=0)
คอนสตรัคเตอร์สำหรับ FIFO queue อาร์กิวเมนต์ maxsize เป็นจำนวนเต็มตั้งขีดจำกัดสูงสุดของจำนวนไอเท็มที่วางในคิวได้ การ insert จะ block เมื่อถึงขนาดนี้ จนกว่า queue items จะถูก consume หาก maxsize น้อยกว่าหรือเท่ากับศูนย์ ขนาดคิวจะเป็น infinite
class Queue.LifoQueue(maxsize=0)
คอนสตรัคเตอร์สำหรับ LIFO queue อาร์กิวเมนต์ maxsize เป็นจำนวนเต็มตั้งขีดจำกัดสูงสุดของจำนวนไอเท็มที่วางในคิวได้ การ insert จะ block เมื่อถึงขนาดนี้ จนกว่า queue items จะถูก consume หาก maxsize น้อยกว่าหรือเท่ากับศูนย์ ขนาดคิวจะเป็น infinite
class Queue.PriorityQueue(maxsize=0)
คอนสตรัคเตอร์สำหรับ priority queue อาร์กิวเมนต์ maxsize เป็นจำนวนเต็มตั้งขีดจำกัดสูงสุดของจำนวนไอเท็มที่วางในคิวได้ การ insert จะ block เมื่อถึงขนาดนี้ จนกว่า queue items จะถูก consume หาก maxsize น้อยกว่าหรือเท่ากับศูนย์ ขนาดคิวจะเป็น infinite
exception Queue.Empty
บ่งชี้ข้อยกเว้นที่ raise เมื่อ non-blocking get() (หรือ get_nowait()) ถูกเรียกบน Queue object ที่ว่าง
exception Queue.Full
บ่งชี้ข้อยกเว้นที่ raise เมื่อ non-blocking put() (หรือ put_nowait()) ถูกเรียกบน Queue object ที่เต็ม
Queue Objects
Queue.qsize() - คืนค่าขนาดประมาณของคิว
Queue.empty() - คืนค่า True หากคิวว่าง False ถ้าไม่ว่าง
Queue.full() - คืนค่า True หากคิวเต็ม False ถ้าไม่เต็ม
Queue.put(item[, block[, timeout]]) - วาง item ลงคิว
Queue.get([block[, timeout]]) - นำ item ออกจากคิวและคืนค่า
Queue.task_done() - บ่งชี้ว่า task ที่ enqueued ไปก่อนหน้านี้เสร็จแล้ว
Queue.join() - Block จนกว่าทุก items ในคิวจะถูก get และ processed
ตัวอย่างโค้ด
import queue # maximum capacity of queue is 20 Q = queue.Queue(maxsize=40) Q.put(50) Q.put(90) Q.put(10) Q.put(70) print(Q.get()) print(Q.get()) print(Q.get()) print(Q.get())
ผลลัพธ์
50 90 10 70
ตัวอย่าง Underflow/Overflow
import queue
Q = queue.Queue(maxsize=30)
print(Q.qsize())
Q.put(50)
Q.put(90)
Q.put(10)
Q.put(70)
print("Full: ", Q.full())
Q.put(90)
Q.put(100)
print("Full: ", Q.full())
print(Q.get())
print(Q.get())
print(Q.get())
print("Empty: ", Q.empty())
print(Q.get())
print(Q.get())
print(Q.get())
print("Empty: ", Q.empty())
print("Full: ", Q.full())
ผลลัพธ์
0 Full: False Full: False 50 90 10 Empty: False 70 90 100 Empty: True Full: False
ตัวอย่างที่ 3 ของ Stack
import queue
S = queue.LifoQueue(maxsize=10)
print(S.qsize())
S.put(50)
S.put(90)
S.put(10)
S.put(70)
S.put(90)
S.put(10)
print("Full: ", S.full())
print("Size: ", S.qsize())
# Data จะถูกเข้าถึงในลำดับย้อนกลับ
print(S.get())
print(S.get())
print(S.get())
print(S.get())
print(S.get())
print("Empty: ", S.empty())
ผลลัพธ์
0 Full: False Size: 6 10 90 70 10 90 Empty: False