DispatchQueue হলো iOS এবং macOS-এ অ্যাসিঙ্ক্রোনাস টাস্ক পরিচালনার জন্য Grand Central Dispatch (GCD)-এর একটি মৌলিক কিউ। Apple Developer Documentation, 2026 অনুসারে, DispatchQueue সিরিয়াল এবং কনকারেন্ট কিউয়ের মাধ্যমে ডেভেলপার থেকে থ্রেড ব্যবস্থাপনাকে বিমূর্ত করে। GCD স্বয়ংক্রিয়ভাবে সিস্টেম থ্রেড পুলে টাস্ক বিতরণ করে, ম্যানুয়াল থ্রেড তৈরি এবং ধ্বংসের প্রয়োজনীয়তা দূর করে।
মূল বিষয়
DispatchQueue হলো Grand Central Dispatch (GCD) ফ্রেমওয়ার্কের একটি অবজেক্ট যা সিস্টেম বা কাস্টম থ্রেড কিউতে টাস্ক এক্সিকিউশন পরিচালনা করে। Grand Central Dispatch একটি নিম্ন-স্তরের Apple লাইব্রেরি, যা iOS 4 এবং macOS 10.6 থেকে উপলব্ধ, যা ডেভেলপার থেকে সম্পূর্ণরূপে থ্রেড ব্যবস্থাপনাকে বিমূর্ত করে। GCD অপারেটিং সিস্টেম থ্রেড পুল ব্যবহার করে এবং ডিভাইসের লোড অনুসারে স্বয়ংক্রিয়ভাবে থ্রেডের সংখ্যা স্কেল করে।
ডেভেলপারকে ম্যানুয়ালি থ্রেড তৈরি এবং ধ্বংস করতে হয় না — GCD এই কাজটি নিজে করে, DispatchQueue-এর মাধ্যমে একটি সহজ API প্রদান করে। ক্লোজার আকারে একটি টাস্ক sync বা async পদ্ধতির মাধ্যমে কিউতে পাঠানো হয়। প্রথম ক্ষেত্রে, কলকারী থ্রেড টাস্ক শেষ না হওয়া পর্যন্ত ব্লক হয়; দ্বিতীয় ক্ষেত্রে, এক্সিকিউশন তাৎক্ষণিকভাবে চলতে থাকে।
Apple (2026) অনুসারে, GCD একটি সিস্টেম থ্রেড পুল ব্যবহার করে যা কোরের সংখ্যা এবং বর্তমান CPU লোডের সাথে খাপ খায়। কনকারেন্ট কিউ প্রতিটি টাস্কের জন্য একটি নতুন থ্রেড তৈরি করে না — GCD পুল থেকে থ্রেড পুনরায় ব্যবহার করে, থ্রেড তৈরির ওভারহেড কমিয়ে আনে।
Grand Central Dispatch তিনটি মূল উপাদান নিয়ে গঠিত: কিউ (DispatchQueue), গ্রুপ (DispatchGroup), এবং সেমাফোর (DispatchSemaphore)। কিউ হল প্রধান উপাদান যা কোড ব্লক আকারে টাস্ক গ্রহণ করে। DispatchGroup একাধিক টাস্কের এক্সিকিউশন সিঙ্ক্রোনাইজ করে, যেখানে DispatchSemaphore একটি শেয়ার্ড রিসোর্সে অ্যাক্সেস নির্দিষ্ট সংখ্যক থ্রেডে সীমাবদ্ধ করে।
প্রতিটি GCD কিউ একটি নির্দিষ্ট QoS (Quality of Service) ক্লাসের সাথে যুক্ত, যা সিস্টেমকে টাস্কের গুরুত্ব সম্পর্কে জানায়। সিস্টেম কিউগুলোর মধ্যে CPU সময় বিতরণ করতে QoS ব্যবহার করে, আরও গুরুত্বপূর্ণ টাস্ককে অগ্রাধিকার দেয় — যেমন UI আপডেট বা ব্যবহারকারী স্পর্শ হ্যান্ডলিং।
সিরিয়াল কিউ টাস্ক কঠোরভাবে ক্রমান্বয়ে নির্বাহ করে, একের পর এক। যদি সিরিয়াল কিউতে তিনটি টাস্ক রাখা হয়, দ্বিতীয়টি প্রথমটি সম্পূর্ণরূপে শেষ হওয়ার পরেই শুরু হয়। সিরিয়াল কিউ শেয়ার্ড রিসোর্সে অ্যাক্সেস সিঙ্ক্রোনাইজ করতে ব্যবহৃত হয় — উদাহরণস্বরূপ, একটি অ্যারে যা কোডের একাধিক অংশ থেকে পরিবর্তিত হয়।
কনকারেন্ট কিউ একসাথে একাধিক টাস্ক চালায়, সিস্টেম পুল থেকে উপলব্ধ থ্রেডে বিতরণ করে। কনকারেন্ট কিউতে টাস্ক FIFO ক্রমে শুরু হয়, কিন্তু যদি তাদের এক্সিকিউশন সময় ভিন্ন হয় তাহলে এলোমেলো ক্রমে শেষ হয়। কনকারেন্ট কিউ শেষ হওয়ার ক্রমের গ্যারান্টি দেয় না — শুধু শুরু হওয়ার ক্রমের।
| প্যারামিটার | সিরিয়াল কিউ | কনকারেন্ট কিউ |
|---|---|---|
| এক্সিকিউশন ক্রম | কঠোরভাবে ক্রমান্বয়িক | সমান্তরাল |
| থ্রেডের সংখ্যা | এক | GCD পুল থেকে একাধিক |
| ব্যবহার | শেয়ার্ড রিসোর্স সুরক্ষা | স্বাধীন গণনা |
| মূল কিউ | হ্যাঁ (মূল থ্রেড) | না |
| ডেডলক ঝুঁকি | একই কিউতে sync করলে উচ্চ | কম |
সিরিয়াল কিউ সেই টাস্কের জন্য আদর্শ যা শেয়ার্ড অবস্থা পরিবর্তন করে — ফাইলে লেখা, ডেটা মডেল আপডেট করা, বা Core Data-এর সাথে কাজ করা। সিরিয়াল কিউ ব্যবহার নিশ্চিত করে যে কোডের দুটি অংশ একই ডেটা একসাথে পরিবর্তন করবে না, অতিরিক্ত লক ছাড়াই রেস কন্ডিশন দূর করে।
কনকারেন্ট কিউ সেই টাস্কের জন্য উপযুক্ত যা একে অপরের উপর নির্ভরশীল নয়: একাধিক ছবি লোড করা, সমান্তরাল নেটওয়ার্ক রিকোয়েস্ট, বা ডেটার ব্যাচ প্রক্রিয়াকরণ। GCD স্বয়ংক্রিয়ভাবে সিদ্ধান্ত নেয় CPU কোরের সংখ্যা এবং বর্তমান সিস্টেম লোডের ভিত্তিতে একসাথে কতগুলো টাস্ক চালাতে হবে।
QoS (Quality of Service) একটি GCD প্রক্রিয়া যা অপারেটিং সিস্টেমকে টাস্কের গুরুত্ব এবং জরুরিতা সম্পর্কে জানায়। সিস্টেম থ্রেড শিডিউলিংয়ের জন্য QoS ব্যবহার করে: উচ্চতর QoS সম্পন্ন টাস্ক বেশি CPU সময় পায় এবং আগে শুরু হয়। কিউ তৈরি করার সময় বা নির্দিষ্ট টাস্ক জমা দেওয়ার সময় QoS মান পাস করা হয়।
GCD-তে পাঁচটি QoS ক্লাস উপলব্ধ। .userInteractive — UI-সম্পর্কিত টাস্কের জন্য সর্বোচ্চ অগ্রাধিকার। .userInitiated — ব্যবহারকারী দ্বারা শুরু করা টাস্কের জন্য। .utility — পটভূমির টাস্কের জন্য যা অগ্রগতি দেখায়। .background — ব্যবহারকারীর অদৃশ্য টাস্কের জন্য। .default — userInitiated এবং utility-এর মধ্যে একটি মধ্যবর্তী স্তর, ডিফল্টরূপে ব্যবহৃত।
Apple (2026) অনুসারে, ভুল QoS নির্বাচন কর্মক্ষমতা সমস্যার সাধারণ কারণগুলোর মধ্যে একটি। QoS .userInteractive দিয়ে পটভূমির ডাউনলোড চালানো UI-এর সংস্থান নেয়, যার ফলে অ্যানিমেশনে মাইক্রো-ল্যাগ হয়। সুপারিশ করা হয় সবচেয়ে কম QoS বেছে নেওয়ার যা এখনও গ্রহণযোগ্য এক্সিকিউশন সময় সরবরাহ করে।
তাৎক্ষণিক প্রদর্শনের জন্য ছবি লোড করার সময়, .userInitiated ব্যবহার করুন — ব্যবহারকারী ফলাফল আশা করে। পরবর্তী স্ক্রিন প্রিলোড করার জন্য, .utility যথেষ্ট। পটভূমির সার্ভার সিঙ্ক্রোনাইজেশন .background দিয়ে চলে, সক্রিয় টাস্কের উপর প্রভাব কমিয়ে।
DispatchGroup টাস্কের একটি গ্রুপ সম্পূর্ণ হওয়া ট্র্যাক করতে দেয়। যখন গ্রুপের সব টাস্ক শেষ হয়, GCD নির্দিষ্ট কিউতে notify হ্যান্ডলার কল করে। এটি বিশেষভাবে উপযোগী যখন একাধিক স্বাধীন রিসোর্স লোড করা হয় — প্রোফাইল ডেটা, বন্ধু তালিকা, এবং সেটিংস — যেখানে সব ডেটা পাওয়ার পরেই ইন্টারফেস আপডেট করা উচিত।
DispatchGroup একটি সিঙ্ক্রোনাস wait() কল সমর্থন করে, যা সব টাস্ক শেষ না হওয়া পর্যন্ত বর্তমান থ্রেড ব্লক করে। এটি সুবিধাজনক যখন কোড গ্রুপের ফলাফল ছাড়া চালিয়ে যেতে পারে না। অ্যাসিঙ্ক্রোনাস ভেরিয়েন্ট notify() সব টাস্ক শেষ হওয়ার পর নির্দিষ্ট কিউতে ক্লোজার কল করে, কলকারী থ্রেড ব্লক না করে।
DispatchSemaphore একটি রিসোর্সে অ্যাক্সেস নিয়ন্ত্রণ করে, একসাথে অ্যাক্সেসের সংখ্যা সীমিত করে। প্রাথমিক মান 3 সহ একটি সেমাফোর তিনটির বেশি সমান্তরাল টাস্কের অনুমতি দেয় না। wait() কল করলে কাউন্টার কমে, signal() কল করলে বাড়ে। যদি কাউন্টার শূন্য হয়, রিসোর্স উপলব্ধ না হওয়া পর্যন্ত থ্রেড ব্লক হয়।
Swift-এ DispatchQueue ব্যবহারের তিনটি ব্যবহারিক উদাহরণ দেখি। প্রথমটি মূল থ্রেডে ফেরত সহ একটি মৌলিক async কল প্রদর্শন করে, দ্বিতীয়টি সিরিয়াল কিউয়ের মাধ্যমে সিঙ্ক্রোনাইজেশন দেখায়, এবং তৃতীয়টি সমান্তরাল রিকোয়েস্টের জন্য DispatchGroup ব্যবহার করে।
DispatchQueue.main হলো মূল থ্রেডের সিরিয়াল কিউ, যা শুধুমাত্র UI অপারেশনের জন্য। পটভূমির কাজ শেষ করার পর ইন্টারফেস আপডেট করতে সর্বদা এটি ব্যবহার করুন।
let queue = DispatchQueue.global(qos: .userInitiated)
queue.async {
let data = self.fetchData()
DispatchQueue.main.async {
self.updateUI(with: data)
}
}
একটি অনন্য আইডেন্টিফায়ার সহ কাস্টম সিরিয়াল কিউ তৈরি করা পরিবর্তনযোগ্য অ্যারেতে অ্যাক্সেস সিঙ্ক্রোনাইজ করে। সব পড়া এবং লেখার অপারেশন একটি একক কিউয়ের মাধ্যমে যায়, রেস কন্ডিশন দূর করে।
let serialQueue = DispatchQueue(label: "com.app.items")
var items: [Int] = []
serialQueue.async {
items.append(1)
}
serialQueue.async {
let last = items.last
DispatchQueue.main.async {
print("Last item: \(last)")
}
}
DispatchGroup কনকারেন্ট কিউতে একাধিক টাস্ক চালু করার এবং সব শেষ হলে নোটিফিকেশন পাওয়ার অনুমতি দেয়। প্রোফাইল স্ক্রিনের জন্য ডেটা লোড করার সময় এটি উপযোগী।
let group = DispatchGroup()
let worker = DispatchQueue.global()
worker.async(group: group) { self.loadProfile() }
worker.async(group: group) { self.loadFriends() }
worker.async(group: group) { self.loadSettings() }
group.notify(queue: DispatchQueue.main) {
self.showCompleteUI()
}
ডেডলক যখন সিরিয়াল কিউতে sync কল করা হয় — সবচেয়ে সাধারণ ভুল। যদি সিরিয়াল কিউতে একটি টাস্ক একই কিউতে queue.sync কল করে, থ্রেড চিরতরে ব্লক হয়। কিউ বর্তমান টাস্ক শেষ হওয়ার অপেক্ষায় থাকে, এবং টাস্ক sync কল শেষ হওয়ার অপেক্ষায় থাকে — একটি ক্লাসিক পারস্পরিক ব্লকিং।
UIKit-এর সাথে সব অপারেশন মূল থ্রেডে করা উচিত। Xcode Main Thread Checker-এর মাধ্যমে ডিবাগ মোডে এই ধরনের ত্রুটি সনাক্ত করে। Release বিল্ডে, এগুলি অপ্রত্যাশিত আচরণ ঘটায়: অ্যানিমেশন শুরু হয় না, UI আপডেট হয় না, ক্র্যাশ হতে পারে।
গ্লোবাল কিউয়ের পরিবর্তে শত শত কাস্টম কিউ তৈরি করা একটি অ্যান্টিপ্যাটার্ন। প্রতিটি কিউ সিস্টেম রিসোর্স ব্যবহার করে। বেশিরভাগ টাস্কের জন্য, বিভিন্ন QoS স্তরের গ্লোবাল কনকারেন্ট কিউ এবং শেয়ার্ড ডেটা সিঙ্ক্রোনাইজ করার জন্য এক বা দুটি সিরিয়াল কিউ যথেষ্ট।
autoreleasepool ছাড়া পটভূমি কিউতে রিসোর্স-নিবিড় লুপ টাস্ক চালানোর সময়, পুরো লুপ শেষ না হওয়া পর্যন্ত মেমরি বাড়তে থাকে। ARC শুধুমাত্র autorelease পুল থেকে বের হওয়ার সময় অবজেক্ট রিলিজ করে। সময়মতো মেমরি বিনামুক্তির জন্য লুপ পুনরাবৃত্তিগুলি autoreleasepool { }-এ মোড়ান।
প্রায়শই জিজ্ঞাসিত প্রশ্ন
OperationQueue GCD-এর উপর নির্মিত কিন্তু অপারেশন ডিপেন্ডেন্সি, KVO এবং বাতিলকরণ সমর্থন সহ একটি উচ্চ-স্তরের API সরবরাহ করে। DispatchQueue ডিপেন্ডেন্সি ম্যানেজমেন্ট ছাড়া সাধারণ async টাস্কের জন্য একটি নিম্ন-স্তরের কিউ।
GCD চলমান টাস্ক থামানো সমর্থন করে না। suspend() মেথড শুধু নতুন টাস্ক থামায়; বর্তমান টাস্ক শেষ পর্যন্ত চলে। বাতিলকরণের জন্য টাস্ক কোডের ভিতরে ম্যানুয়াল ফ্ল্যাগ চেক করা প্রয়োজন।
তাৎক্ষণিক ফলাফল প্রদর্শন সহ মূল রিকোয়েস্টের জন্য — .userInitiated. ডেটা প্রিলোডিংয়ের জন্য — .utility. পটভূমি সিঙ্ক্রোনাইজেশনের জন্য — .background.
GCD থ্রেডের সংখ্যা নির্ধারণ করে না। থ্রেড পুল লোডের অধীনে গতিশীলভাবে স্কেল হয়, CPU কোর, বর্তমান লোড এবং প্রতিটি টাস্কের QoS বিবেচনা করে। সর্বোচ্চ সংখ্যা সিস্টেম দ্বারা সীমিত।
UIKit থ্রেড-নিরাপদ নয় — এর সব ক্লাস শুধুমাত্র মূল থ্রেড থেকে কল করা উচিত। লঙ্ঘন অপ্রত্যাশিত আচরণ, মিসড আপডেট এবং Production-এ ক্র্যাশ ঘটায়।
সারসংক্ষেপ
আমরা একটি মোবাইল অ্যাপ্লিকেশন টার্নকি তৈরি করব
IT Sectr 2017 সাল থেকে স্টার্টআপ এবং ব্যবসার জন্য iOS এবং Android অ্যাপ্লিকেশন তৈরি করে। আমরা আপনাকে পরামর্শ দেব এবং সেরা সমাধান প্রস্তাব করব।
আরও পড়ুন