Computer >> คอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Python

กองและจัดคิวใน Python โดยใช้โมดูลคิว


ใน Python การใช้โครงสร้างข้อมูลแบบสแต็กและคิวทำได้ง่ายมาก Stack เรียกว่า LIFO เนื่องจาก Stack ทำงานบนหลักการของ "เข้าก่อนออกก่อน" และเรียกคิวว่า FIFO เนื่องจาก Queue ทำงานบนหลักการ "เข้าก่อนออกก่อน" และฟังก์ชัน inbuilt ใน Python ทำให้ รหัสสั้นและเรียบง่าย

โมดูลคิวใช้คิวหลายผู้ผลิต ผู้บริโภคหลายราย และมีประโยชน์อย่างยิ่งในการเขียนโปรแกรมเธรดเมื่อข้อมูลต้องแลกเปลี่ยนอย่างปลอดภัยระหว่างหลายเธรด คลาส Queue ในโมดูลนี้ใช้ความหมายการล็อกที่จำเป็นทั้งหมด และขึ้นอยู่กับความพร้อมใช้งานของการสนับสนุนเธรดใน Python

โมดูลนี้ใช้คิวสามประเภท ซึ่งแตกต่างกันในลำดับที่ดึงข้อมูลรายการเท่านั้น สำหรับคิว FIFO งานแรกที่เพิ่มคืองานแรกที่ดึงออกมา และสำหรับคิว LIFO รายการที่เพิ่มล่าสุดคืองานแรกที่ดึงออกมา (ทำงานเหมือนสแต็ก) และสำหรับคิวลำดับความสำคัญ รายการจะถูกจัดเรียงไว้ (โดยใช้โมดูล heapq) และดึงข้อมูลรายการที่มีค่าต่ำสุดก่อน

โมดูลคิวนี้กำหนดคลาสและข้อยกเว้นต่อไปนี้

คลาส Queue.Queue(maxsize=0)

นี่คือตัวสร้างสำหรับคิว FIFO อาร์กิวเมนต์ maxsize เป็นจำนวนเต็มที่ตั้งค่าขีดจำกัดบนของจำนวนรายการที่สามารถวางในคิว การแทรกจะบล็อกเมื่อถึงขนาดนี้ จนกว่าจะใช้รายการในคิว หากขนาดสูงสุดน้อยกว่าหรือเท่ากับศูนย์ ขนาดคิวจะไม่มีที่สิ้นสุด

คลาส Queue.LifoQueue(maxsize=0)

นี่คือตัวสร้างสำหรับคิว LIFO อาร์กิวเมนต์ maxsize เป็นจำนวนเต็มที่ตั้งค่าขีดจำกัดบนของจำนวนรายการที่สามารถวางในคิว การแทรกจะบล็อกเมื่อถึงขนาดนี้ จนกว่าจะใช้รายการในคิว หากขนาดสูงสุดน้อยกว่าหรือเท่ากับศูนย์ ขนาดคิวจะไม่มีที่สิ้นสุด

คลาส Queue.PriorityQueue(maxsize=0)

นี่คือตัวสร้างสำหรับคิวลำดับความสำคัญ อาร์กิวเมนต์ maxsize เป็นจำนวนเต็มที่ตั้งค่าขีดจำกัดบนของจำนวนรายการที่สามารถวางในคิว การแทรกจะบล็อกเมื่อถึงขนาดนี้ จนกว่าจะใช้รายการในคิว หากขนาดสูงสุดน้อยกว่าหรือเท่ากับศูนย์ ขนาดคิวจะไม่มีที่สิ้นสุด

คิวข้อยกเว้น ว่างเปล่า

บรรทัดนี้ระบุว่ามีข้อยกเว้นเกิดขึ้นเมื่อมีการเรียกใช้การไม่บล็อก get() (หรือ get_nowait()) บนออบเจกต์ Queue ซึ่งว่างเปล่า

ยกเว้นคิวเต็ม

บรรทัดนี้ระบุว่ามีข้อยกเว้นเกิดขึ้นเมื่อมีการเรียก non-blocking put() (หรือ put_nowait()) บนออบเจกต์ Queue ซึ่งเต็ม

คิววัตถุ

Queue.qsize()

ฟังก์ชันนี้ส่งคืนขนาดโดยประมาณของคิว

Queue.empty()

ฟังก์ชันนี้จะคืนค่า True หากคิวว่าง มิฉะนั้นจะเป็น False หาก empty() คืนค่า True จะไม่รับประกันว่าการเรียก put() ครั้งต่อไปจะไม่ถูกบล็อก ในทำนองเดียวกัน หาก empty() คืนค่า False จะไม่รับประกันว่าการเรียก get() ครั้งต่อไปจะไม่ถูกบล็อก

Queue.full()

คืนค่า True หากคิวเต็ม มิฉะนั้นจะเป็น False หาก full() คืนค่าเป็น True จะไม่รับประกันว่าการเรียก get() ครั้งต่อไปจะไม่ถูกบล็อก ในทำนองเดียวกัน หาก full() คืนค่า False จะไม่รับประกันว่าการเรียก put() ครั้งต่อไปจะไม่ถูกบล็อก

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

วางรายการลงในคิว หากการบล็อก args ที่เป็นตัวเลือกเป็นจริงและการหมดเวลาคือไม่มี (ค่าเริ่มต้น) ให้บล็อกหากจำเป็นจนกว่าช่องว่างจะพร้อมใช้งาน หากการหมดเวลาเป็นจำนวนบวก จะบล็อกการหมดเวลาสูงสุดในไม่กี่วินาทีและทำให้เกิดข้อยกเว้นแบบเต็มหากไม่มีช่องว่างภายในเวลานั้น มิฉะนั้น (บล็อกเป็นเท็จ) ให้วางรายการในคิวหากมีช่องว่างทันที มิฉะนั้นจะทำให้เกิดข้อยกเว้นแบบเต็ม (ในกรณีนี้จะละเว้นการหมดเวลา)

Queue.get([block[, timeout]])

ลบและส่งคืนสินค้าจากคิว หากการบล็อก args ที่เป็นตัวเลือกเป็นจริงและการหมดเวลาคือไม่มี (ค่าเริ่มต้น) ให้บล็อกหากจำเป็นจนกว่ารายการจะพร้อมใช้งาน หากระยะหมดเวลาเป็นจำนวนบวก จะบล็อกการหมดเวลาสูงสุดเป็นวินาที และเพิ่มข้อยกเว้นว่างหากไม่มีรายการใดพร้อมใช้งานภายในเวลานั้น มิฉะนั้น (การบล็อกเป็นเท็จ) ให้ส่งคืนสินค้าหากมีรายการใดรายการหนึ่งพร้อมใช้งานทันที มิฉะนั้น ให้ยกข้อยกเว้นที่ว่างเปล่า (การหมดเวลาจะถูกละเว้นในกรณีนั้น)

Queue.task_done()

บ่งชี้ว่างานที่จัดคิวไว้ก่อนหน้านี้เสร็จสมบูรณ์ ใช้โดยเธรดผู้ใช้คิว สำหรับแต่ละ get() ที่ใช้ในการดึงข้อมูลงาน การเรียก task_done() ครั้งต่อไปจะบอกคิวว่าการประมวลผลงานเสร็จสมบูรณ์

หาก join() กำลังบล็อกอยู่ จะกลับมาทำงานต่อเมื่อรายการทั้งหมดได้รับการประมวลผลแล้ว (หมายความว่าได้รับการเรียก task_done() สำหรับทุกรายการที่ใส่ () ลงในคิว)

เพิ่ม ValueError หากถูกเรียกมากกว่าจำนวนรายการที่อยู่ในคิว

Queue.join()

บล็อกจนกว่าจะได้รับและประมวลผลรายการทั้งหมดในคิว

จำนวนงานที่ยังไม่เสร็จจะเพิ่มขึ้นทุกครั้งที่มีการเพิ่มรายการลงในคิว การนับจะลดลงเมื่อใดก็ตามที่เธรดของผู้บริโภคเรียก task_done() เพื่อระบุว่ามีการดึงไอเท็มและการทำงานทั้งหมดบนนั้นเสร็จสมบูรณ์ เมื่อจำนวนงานที่ยังไม่เสร็จเหลือศูนย์ ให้ join() เลิกบล็อก

โค้ดตัวอย่าง

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 ของสแต็ก

import queue
S = queue.LifoQueue(maxsize=10)
# qsize() give the maxsize of
# the Queue
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 will be accessed in the
# reverse order Reverse of that
# of Queue
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