1. คิวใน Python คืออะไร?

แนวคิดพื้นฐานของคิว

คิว (Queue) เป็นหนึ่งในโครงสร้างข้อมูล ซึ่งใช้วิธีการที่เรียกว่า “FIFO (First In, First Out)” กล่าวคือ องค์ประกอบที่ถูกเพิ่มเข้ามาก่อนจะถูกนำออกก่อนตามลำดับ กลไกนี้ถูกใช้อย่างแพร่หลายในงานวิทยาการคอมพิวเตอร์และการเขียนโปรแกรม และเป็นเครื่องมือที่จำเป็นสำหรับการประมวลผลข้อมูลอย่างมีประสิทธิภาพ ตัวอย่างเช่น มีการใช้คิวในสถานการณ์ต่อไปนี้:
  • การจัดตารางงาน: ดำเนินการงานที่เริ่มก่อนตามลำดับ
  • การบัฟเฟอร์: เก็บข้อมูลสตรีมไว้ในคิวเป็นจำนวนหนึ่ง แล้วประมวลผลตามลำดับ
  • การสื่อสารระหว่างเธรดหลายตัว: เมื่อหลายเธรดประมวลผลข้อมูลพร้อมกัน สามารถใช้คิวเพื่อจัดการลำดับของข้อมูลได้
โมดูล queue ที่มีในไลบรารีมาตรฐานของ Python เป็นเครื่องมืออันทรงพลังที่ช่วยให้การทำงานกับคิวเหล่านี้ทำได้ง่ายขึ้น โมดูลนี้มีกลไกการล็อกภายในเพื่อให้สามารถแลกเปลี่ยนข้อมูลระหว่างเธรดได้อย่างปลอดภัย

2. การใช้งานคิวใน Python

การใช้งานทั่วไปของคิว

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

3. queue โมดูล: ภาพรวม

คำอธิบายคลาส

ใน Python queue โมดูลมีคลาสหลักอยู่ 3 คลาสให้ใช้งาน ต่อไปนี้จะแนะนำคุณลักษณะและวิธีใช้งานของแต่ละคลาส。
  1. Queue(คิวแบบ FIFO)
    • เป็นคิวพื้นฐานที่สุด รายการที่ถูกเพิ่มก่อนจะถูกนำออกก่อน ใช้รูปแบบ FIFO (First In, First Out)
    • ตัวอย่างการใช้งาน:
    import queue q = queue.Queue() q.put("task1") q.put("task2") print(q.get()) ## จะแสดง "task1"
  2. LifoQueue(คิวแบบ LIFO)
    • ทำงานเหมือนสแตก รายการที่ถูกเพิ่มล่าสุดจะถูกนำออกก่อน ใช้รูปแบบ LIFO (Last In, First Out)
    • ตัวอย่างการใช้งาน:
    import queue q = queue.LifoQueue() q.put("task1") q.put("task2") print(q.get()) ## จะแสดง "task2"
  3. PriorityQueue(คิวแบบลำดับความสำคัญ)
    • ดึงรายการตามลำดับความสำคัญ ค่ายิ่งต่ำยิ่งถือว่ามีความสำคัญสูงกว่า
    • ตัวอย่างการใช้งาน: import queue q = queue.PriorityQueue() q.put((1, "task1")) q.put((3, "task3")) q.put((2, "task2")) print(q.get()) ## จะแสดง "(1, 'task1')"
สิ่งสำคัญคือการเลือกใช้คลาสเหล่านี้ให้เหมาะกับสถานการณ์ที่แตกต่างกัน。

4. วิธีการนำคิวแบบ FIFO ไปใช้งาน

วิธีใช้งานพื้นฐาน

คิวแบบ FIFO เป็นรูปแบบคิวที่ใช้บ่อยที่สุด การใช้งานด้วย queue.Queue ทำได้ง่ายมาก ด้านล่างเป็นตัวอย่างการใช้งานพื้นฐานของคิวแบบ FIFO ในภาษา Python
import queue

## การสร้างคิวแบบ FIFO
q = queue.Queue()

## เพิ่มรายการลงในคิว
q.put("apple")
q.put("banana")
q.put("cherry")

## ดึงรายการออกจากคิว
while not q.empty():
    print(q.get())
ในโค้ดนี้ รายการจะถูกดึงออกมาตามลำดับ "apple", "banana", "cherry" และแต่ละรายการจะถูกแสดงผล โดยใช้เมธอด empty() เพื่อวนทำงานจนกว่าคิวจะว่าง

ตัวอย่างการใช้งานจริง

ตัวอย่างเช่น เมื่อประมวลผลคำขอที่เว็บเซิร์ฟเวอร์ได้รับ อาจเพิ่มแต่ละคำขอลงในคิวแล้วประมวลผลตามลำดับ ในสถานการณ์เช่นนี้ คิวแบบ FIFO ทำงานได้อย่างมีประสิทธิภาพ
侍エンジニア塾

5. การใช้งานคิวขั้นสูง

เมธอดของคิว

ในโมดูล queue ของ Python มีเมธอดที่มีประโยชน์จำนวนมากสำหรับการจัดการคิวอย่างมีประสิทธิภาพ การนำมาใช้จะช่วยให้ทำงานขั้นสูงได้มากขึ้น ต่อไปนี้คือเมธอดหลักบางส่วน
  1. qsize()
    • ส่งคืนจำนวนองค์ประกอบที่เก็บอยู่ในคิว สะดวกสำหรับตรวจสอบว่าคิวว่างหรือไม่
    • ตัวอย่างการใช้งาน:
    q = queue.Queue() q.put("task1") print(q.qsize()) ## จะแสดงผลเป็น 1
  2. empty()
    • ตรวจสอบว่าคิวว่างหรือไม่ จะส่งคืน True หรือ False
    • ตัวอย่างการใช้งาน:
    q = queue.Queue() print(q.empty()) ## จะแสดงผลเป็น True
  3. full()
    • ตรวจสอบว่าคิวเต็มหรือไม่ มีผลเมื่อมีการกำหนด maxsize
    • ตัวอย่างการใช้งาน:
    q = queue.Queue(maxsize=2) q.put("task1") q.put("task2") print(q.full()) ## จะแสดงผลเป็น True
  4. put(item)
    • เพิ่มรายการลงในคิว โดยปกติตั้งค่า block=True ไว้ ซึ่งอาจทำให้บล็อกได้ และสามารถกำหนดค่า timeout เพื่อจำกัดการทำงานได้
    • ตัวอย่างการใช้งาน:
    q = queue.Queue() q.put("task1")
  5. get()
    • ดึงรายการออกจากคิว หากไม่มีรายการอยู่และกำหนด block=True จะรอจนกว่าจะมีการเพิ่มรายการ
    • ตัวอย่างการใช้งาน: q = queue.Queue() q.put("task1") task = q.get() print(task) ## จะแสดงผลเป็น "task1"
การใช้เมธอดเหล่านี้ช่วยให้จัดการคิวได้อย่างมีประสิทธิภาพ และสามารถทำการจัดการข้อมูลที่ซับซ้อนได้มากขึ้น

6. การจัดการข้อยกเว้นในคิว

การจัดการข้อยกเว้นของคิว

queue เป็นโมดูลที่มีข้อยกเว้นไว้สำหรับจัดการข้อผิดพลาดที่เกิดขึ้นระหว่างการดึงรายการออกจากคิวอย่างมีประสิทธิภาพ ซึ่งช่วยให้สามารถจัดการพฤติกรรมเมื่อเกิดข้อผิดพลาดได้อย่างเหมาะสม
  1. queue.Full
    • จะเกิดขึ้นเมื่อเรียก put() ขณะที่คิวเต็ม
    • ตัวอย่างการจัดการข้อยกเว้น:
    try: q.put("task", block=False) except queue.Full: print("คิวเต็ม")
  2. queue.Empty
    • จะเกิดขึ้นเมื่อเรียก get() ขณะที่คิวว่างเปล่า
    • ตัวอย่างการจัดการข้อยกเว้น: try: task = q.get(block=False) except queue.Empty: print("คิวว่าง")
ข้อยกเว้นเหล่านี้มีความสำคัญเป็นพิเศษเมื่อใช้การดำเนินการแบบบล็อก แนะนำให้จัดการข้อผิดพลาดอย่างเหมาะสมเพื่อป้องกันไม่ให้โปรแกรมหยุดทำงานจากข้อผิดพลาด

7. การใช้คิวในมัลติเธรดของ Python

การจัดการงานในมัลติเธรด

โมดูลqueueของ Python มีประโยชน์อย่างยิ่งในสภาพแวดล้อมแบบมัลติเธรด การใช้คิวช่วยให้สามารถแชร์ข้อมูลระหว่างเธรดได้อย่างปลอดภัย และกระจายงานได้อย่างมีประสิทธิภาพ ต่อไปนี้คือตัวอย่างง่ายๆ
import queue
import threading

## การสร้างคิว
q = queue.Queue()

## กำหนดเธรดทำงาน (worker thread)
def worker():
    while True:
        item = q.get()
        print(f"กำลังประมวลผล: {item}")
        q.task_done()

## เริ่มเธรด
threading.Thread(target=worker, daemon=True).start()

## เพิ่มงานลงในคิว
for item in range(5):
    q.put(item)

## รอให้งานทั้งหมดเสร็จสิ้น
q.join()
print("งานทั้งหมดเสร็จสิ้นแล้ว")
ในโปรแกรมนี้ เธรดหลายตัวจะดึงงานออกจากคิวมาประมวลผลพร้อมกัน และรอจนกว่างานทั้งหมดจะเสร็จสิ้น การใช้คิวช่วยหลีกเลี่ยงการชนกันของข้อมูลระหว่างเธรด พร้อมทั้งทำให้สามารถประมวลผลแบบขนานได้อย่างมีประสิทธิภาพ

8. การใช้คิวแบบมีขีดจำกัด (Bounded Queue)

คิวแบบมีขีดจำกัดคืออะไร?

คิวแบบมีขีดจำกัด (Bounded Queue) คือคิวที่กำหนดความจุสูงสุดไว้ คิวประเภทนี้มีประโยชน์ในการป้องกันการใช้ทรัพยากรอย่างสิ้นเปลืองภายใต้เงื่อนไขบางประการ ตัวอย่างเช่น เมื่อเว็บเซิร์ฟเวอร์ต้องจัดการคำขอจำนวนมาก การกำหนดขีดจำกัดจะช่วยหลีกเลี่ยงการทำให้ระบบทำงานเกินกำลัง คิวแบบมีขีดจำกัดมีคุณสมบัติหลักดังต่อไปนี้。
  1. พฤติกรรมเมื่อไม่สามารถเพิ่มไอเทมได้ เมื่อคิวเต็มและพยายามเพิ่มไอเทมใหม่ จะเกิดพฤติกรรมตามที่กำหนดไว้ตามความจุของคิว พฤติกรรมทั่วไปมีอยู่ 2 แบบดังนี้。
  • ปฏิเสธไอเทมใหม่:เมื่อคิวเต็ม จะไม่รับไอเทมเพิ่มเติม และการเพิ่มไอเทมใหม่จะถูกปฏิเสธ。
  • เขียนทับไอเทมเก่า:ลบไอเทมที่เก่าที่สุดในคิว แล้วเพิ่มไอเทมใหม่เข้าแทนที่。
  1. การจัดการทรัพยากร คิวแบบมีขีดจำกัดถูกใช้เพื่อจัดการทรัพยากร (หน่วยความจำและ CPU เป็นต้น) อย่างมีประสิทธิภาพ ช่วยหลีกเลี่ยงการใช้ทรัพยากรอย่างสูญเปล่า และเป็นประโยชน์เมื่อประมวลผลงานภายในขอบเขตที่จำกัด。

ตัวอย่างการใช้งาน

ด้านล่างคือตัวอย่างการใช้งานคิวแบบมีขีดจำกัดใน Python。
import queue

## สร้างคิวแบบมีขีดจำกัด
q = queue.Queue(maxsize=3)

## เพิ่มไอเทมลงในคิว
q.put("task1")
q.put("task2")
q.put("task3")

## หากพยายามเพิ่มไอเทมเพิ่มเติม อาจบล็อกหรือเกิดข้อยกเว้น
try:
    q.put_nowait("task4")
except queue.Full:
    print("คิวเต็มแล้ว")
ในตัวอย่างนี้ ได้กำหนดขนาดสูงสุดของคิวเป็น 3 และเมื่อพยายามเพิ่มไอเทมชิ้นที่ 4 จะเกิดข้อยกเว้น queue.Full ขึ้น คิวแบบมีขีดจำกัดจึงมีประสิทธิภาพในการป้องกันไม่ให้ระบบทำงานเกินกำลัง。

9. บทสรุป

โมดูล queue ของ Python เป็นเครื่องมือที่มีประโยชน์อย่างยิ่งในหลายสถานการณ์ เช่น การประมวลผลแบบขนานและการสื่อสารระหว่างเธรด โดยช่วยจัดการข้อมูลได้อย่างมีประสิทธิภาพ โดยเฉพาะอย่างยิ่ง การใช้คิวแบบ FIFO, LIFO และคิวแบบมีลำดับความสำคัญ ช่วยให้สามารถจัดการข้อมูลได้อย่างยืดหยุ่น รองรับหลากหลายสถานการณ์ นอกจากนี้ การนำการจัดการข้อยกเว้นและคิวแบบจำกัดมาใช้ จะช่วยเสริมความสามารถในการจัดการข้อผิดพลาดและการบริหารทรัพยากรให้มีประสิทธิภาพยิ่งขึ้น เมื่อทำการประมวลผลข้อมูลที่ซับซ้อนด้วย Python ขอแนะนำให้ลองใช้ความสามารถเหล่านี้ดู
年収訴求