পাইথনে স্ট্যাক এবং কিউ ডেটা স্ট্রাকচার ইমপ্লিমেন্ট করা খুব সহজ। স্টাকে LIFO বলা হয় কারণ স্ট্যাক "Last-in, first-out" নীতিতে কাজ করে এবং কিউ FIFO বলা হয় কারণ কিউ "First-in, first-out" নীতিতে কাজ করে। পাইথনের ইনবিল্ট ফাংশনগুলো কোডকে ছোট ও সহজ করে দেয়।
Queue মডিউল মাল্টি-প্রোডিউসার, মাল্টি-কনসিউমার কিউ ইমপ্লিমেন্ট করে এবং এটি থ্রেডেড প্রোগ্রামিং-এ বিশেষভাবে উপযোগী যখন একাধিক থ্রেডের মধ্যে নিরাপদে ইনফরমেশন এক্সচেঞ্জ করতে হয়। এই মডিউলের Queue ক্লাস সকল প্রয়োজনীয় লকিং সেমান্টিক্স ইমপ্লিমেন্ট করে এবং এটি পাইথনে থ্রেড সাপোর্টের উপলব্ধতার ওপর নির্ভর করে।
এই মডিউল তিন ধরনের কিউ ইমপ্লিমেন্ট করে, যেগুলো শুধু এন্ট্রি রিট্রিভ করার ক্রমে ভিন্ন। FIFO কিউতে, প্রথমে অ্যাড করা টাস্কগুলো প্রথমে রিট্রিভ হয় এবং LIFO কিউতে, সবচেয়ে اخیر যোগ করা এন্ট্রি প্রথমে রিট্রিভ হয় (স্ট্যাক처럼 কাজ করে)। আর প্রায়োরিটি কিউতে, এন্ট্রিগুলো সর্টেড থাকে (heapq মডিউল ব্যবহার করে) এবং সবচেয়ে কম ভ্যালুযুক্ত এন্ট্রি প্রথমে রিট্রিভ হয়।
এই queue মডিউল নিচের ক্লাস ও এক্সেপশন সংজ্ঞায়িত করে:
class Queue.Queue(maxsize=0)
FIFO কিউয়ের কনস্ট্রাক্টর। maxsize আর্গুমেন্ট একটি ইন্টিজার যা কিউতে রাখা আইটেমের সংখ্যার আপার বাউন্ড লিমিট সেট করে। এই সাইজ পৌঁছালে ইনসারশন ব্লক হবে, যতক্ষণ না কিউ আইটেম কনজিউম হয়। maxsize যদি শূন্য বা ঋণাত্মক হয়, কিউ সাইজ অনন্ত হবে।
class Queue.LifoQueue(maxsize=0)
LIFO কিউয়ের কনস্ট্রাক্টর। maxsize আর্গুমেন্ট একটি ইন্টিজার যা কিউতে রাখা আইটেমের সংখ্যার আপার বাউন্ড লিমিট সেট করে। এই সাইজ পৌঁছালে ইনসারশন ব্লক হবে, যতক্ষণ না কিউ আইটেম কনজিউম হয়। maxsize যদি শূন্য বা ঋণাত্মক হয়, কিউ সাইজ অনন্ত হবে।
class Queue.PriorityQueue(maxsize=0)
প্রায়োরিটি কিউয়ের কনস্ট্রাক্টর। maxsize আর্গুমেন্ট একটি ইন্টিজার যা কিউতে রাখা আইটেমের সংখ্যার আপার বাউন্ড লিমিট সেট করে। এই সাইজ পৌঁছালে ইনসারশন ব্লক হবে, যতক্ষণ না কিউ আইটেম কনজিউম হয়। maxsize যদি শূন্য বা ঋণাত্মক হয়, কিউ সাইজ অনন্ত হবে।
exception Queue.Empty
এই লাইনটি ইন্ডিকেট করে যে non-blocking get() (বা get_nowait()) খালি Queue অবজেক্টে কল হলে এক্সেপশন উত্থাপিত হয়।
exception Queue.Full
এই লাইনটি ইন্ডিকেট করে যে non-blocking put() (বা put_nowait()) পুরো Queue অবজেক্টে কল হলে এক্সেপশন উত্থাপিত হয়।
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 block true এবং timeout None (ডিফল্ট) হলে, ফ্রি স্লট উপলব্ধ হওয়া পর্যন্ত ব্লক করুন। timeout পজিটিভ নম্বর হলে, hoogstens timeout সেকেন্ড ব্লক করে এবং সেই সময়ের মধ্যে ফ্রি স্লট না থাকলে Full এক্সেপশন উত্থাপন করে। অন্যথায় (block false হলে), ফ্রি স্লট তাত্ক্ষণিক উপলব্ধ থাকলে আইটেম কিউতে যোগ করুন, অন্যথায় Full এক্সেপশন উত্থাপন করুন (timeout কেসে উপেক্ষা করা হয়)।
Queue.get([block[, timeout]])
কিউ থেকে একটি আইটেম সরিয়ে ফেরত দিন। অপশনাল args block true এবং timeout None (ডিফল্ট) হলে, আইটেম উপলব্ধ হওয়া পর্যন্ত ব্লক করুন। timeout পজিটিভ নম্বর হলে, hoogstens timeout সেকেন্ড ব্লক করে এবং সেই সময়ের মধ্যে আইটেম না থাকলে Empty এক্সেপশন উত্থাপন করে। অন্যথায় (block false হলে), আইটেম তাত্ক্ষণিক উপলব্ধ থাকলে ফেরত দিন, অন্যথায় Empty এক্সেপশন উত্থাপন করুন (timeout কেসে উপেক্ষা করা হয়)।
Queue.task_done()
একটি পূর্বে এনকিউড করা টাস্ক কমপ্লিট হয়েছে তা ইন্ডিকেট করে। কিউ কনসিউমার থ্রেড দ্বারা ব্যবহৃত। প্রতিটি get() যেটি টাস্ক ফেচ করতে ব্যবহৃত হয়, তার জন্য পরবর্তী task_done() কল কিউকে বলে যে টাস্কে প্রসেসিং কমপ্লিট হয়েছে।
যদি join() বর্তমানে ব্লকিং থাকে, এটি রিজিউম হবে যখন সব আইটেম প্রসেসড হয়ে যাবে (অর্থাৎ, put() করা প্রতিটি আইটেমের জন্য task_done() কল পাওয়া যাবে)।
যদি কিউতে রাখা আইটেমের চেয়ে বেশি বার কল করা হয়, ValueError উত্থাপন করবে।
Queue.join()
কিউতে থাকা সব আইটেম গেট ও প্রসেসড হওয়া পর্যন্ত ব্লক করে।
অনফিনিশড টাস্কের কাউন্ট বাড়ে যখন কোনো আইটেম কিউতে যোগ হয়। কাউন্ট কমে যখন কনসিউমার থ্রেড task_done() কল করে ইন্ডিকেট করে যে আইটেমটি রিট্রিভ হয়েছে এবং সেটার ওপর সব কাজ কমপ্লিট। অনফিনিশড টাস্কের কাউন্ট শূন্য হলে join() আনব্লক হয়।
উদাহরণ কোড
import queue # কিউর সর্বোচ্চ ক্যাপাসিটি ২০ 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
আন্ডারফ্লো/ওভারফ্লো উদাহরণ
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
স্ট্যাক উদাহরণ (Example 3)
import queue
S = queue.LifoQueue(maxsize=10)
# qsize() কিউর maxsize দেয়
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())
# ডেটা উল্টো ক্রমে এক্সেস হবে
# কিউর বিপরীত
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