Swift-এ মাল্টিথ্রেডিং এবং কনকারেন্সি ব্যবহার করে প্রোগ্রামের একাধিক অংশ একসঙ্গে চালানো সম্ভব। এটি প্রোগ্রামের পারফরম্যান্স বৃদ্ধি এবং দ্রুততর করতে সাহায্য করে, বিশেষত যখন বিভিন্ন টাস্ক একসঙ্গে বা প্যারালালে সম্পন্ন করতে হয়।
Swift-এ মাল্টিথ্রেডিং এবং কনকারেন্সি
মাল্টিথ্রেডিং (Multithreading)
মাল্টিথ্রেডিং হলো এমন একটি পদ্ধতি যেখানে একাধিক থ্রেড (অপারেশনাল ইউনিট) একসঙ্গে এক্সিকিউট করা হয়। প্রতিটি থ্রেড একটি নির্দিষ্ট টাস্ক সম্পন্ন করে এবং একই প্রোগ্রামের অংশ হিসেবে কাজ করে। মাল্টিথ্রেডিংয়ের মাধ্যমে প্রোগ্রাম একাধিক কাজ প্যারালালে করতে পারে, যেমন UI আপডেট করা এবং ব্যাকগ্রাউন্ড প্রসেসিং করা।
কনকারেন্সি (Concurrency)
কনকারেন্সি হলো এমন একটি প্রোগ্রামিং প্যাটার্ন যেখানে একাধিক টাস্ক একই সময়ে সম্পন্ন করার চেষ্টা করা হয়। Swift-এ কনকারেন্সি ম্যানেজ করতে প্রধানত Grand Central Dispatch (GCD) এবং অপারেশন কুইউ (Operation Queue) ব্যবহার করা হয়।
কনকারেন্সি ব্যবহারের পদ্ধতি:
Grand Central Dispatch (GCD):
- GCD হলো একটি লো-লেভেল API, যা কোড ব্যাকগ্রাউন্ডে বা নির্দিষ্ট থ্রেডে চালানোর জন্য ব্যবহৃত হয়।
DispatchQueueএর মাধ্যমে বিভিন্ন থ্রেড তৈরি করা যায়।
অপারেশন কুইউ (Operation Queue):
- এটি GCD এর উপর ভিত্তি করে উচ্চ-লেভেলের API, যা টাস্ক এবং তাদের ডিপেন্ডেন্সি ম্যানেজ করতে সহজ করে।
OperationQueueব্যবহার করে একাধিক টাস্ক কুইউ করা যায়, এবং সেগুলো নির্দিষ্ট অর্ডারে বা প্যারালালে এক্সিকিউট করা যায়।
Swift 5-এ Async/Await
Swift 5 থেকে async/await কনকারেন্সি মডেল চালু করা হয়েছে, যা কনকারেন্সি ম্যানেজমেন্টকে আরও সহজ ও পাঠযোগ্য করে তোলে।
func fetchData() async -> String {
return "Data fetched"
}
Task {
let data = await fetchData()
print(data)
}
মাল্টিথ্রেডিং এবং কনকারেন্সি ব্যবহারের সুবিধা
- পারফরম্যান্স বৃদ্ধি: একাধিক টাস্ক প্যারালালে সম্পন্ন হওয়ায় প্রোগ্রামের কর্মক্ষমতা বাড়ে।
- ব্যাকগ্রাউন্ড প্রসেসিং: হেভি টাস্কগুলো ব্যাকগ্রাউন্ডে চালিয়ে মেইন থ্রেড ফ্রি রাখা যায়, ফলে UI মসৃণ থাকে।
- সহজ এবং ক্লিন কোড:
async/awaitব্যবহারের মাধ্যমে কোড আরও ক্লিন এবং সহজপাঠ্য হয়।
সতর্কতা
কনকারেন্ট কোডিংয়ে ডেটা রেস এবং ডেডলকের মতো সমস্যা হতে পারে, যদি ডেটা অ্যাক্সেস সঠিকভাবে ম্যানেজ না করা হয়। DispatchQueue এর sync এবং async অপশনগুলো সাবধানে ব্যবহার করা উচিত।
সংক্ষেপে
Swift-এ মাল্টিথ্রেডিং এবং কনকারেন্সি প্রোগ্রামের কর্মক্ষমতা এবং দক্ষতা বাড়াতে গুরুত্বপূর্ণ ভূমিকা পালন করে। GCD, OperationQueue, এবং async/await এর মাধ্যমে কোডকে দ্রুত, কার্যকর এবং সহজে পরিচালনাযোগ্য করা যায়।
Swift-এ GCD (Grand Central Dispatch) হলো একটি শক্তিশালী টুল, যা Concurrency বা একাধিক কাজ একসাথে সমান্তরালভাবে সম্পন্ন করতে ব্যবহৃত হয়। এটি Apple-এর একটি API, যা ব্যাকগ্রাউন্ড থ্রেড বা কাজ চালাতে সাহায্য করে, ফলে প্রোগ্রাম আরও কার্যকর এবং দ্রুতগতিসম্পন্ন হয়। GCD ব্যবহার করে আমরা সহজেই অ্যাসিনক্রোনাস কাজ (যেমন, নেটওয়ার্ক কল, ব্যাকগ্রাউন্ড প্রসেসিং) সম্পন্ন করতে পারি এবং মেইন থ্রেডে কাজ করতে পারি, যাতে ইউজার ইন্টারফেস (UI) সঠিকভাবে রেসপন্স করে।
GCD কীভাবে কাজ করে?
GCD মূলত কিউ (Queue) এবং টাস্ক (Task) এর ভিত্তিতে কাজ করে। Queue-তে আমরা যে কাজগুলো পাঠাই, সেগুলো একটি নির্দিষ্ট ক্রমে বা সমান্তরালভাবে সম্পন্ন হয়। GCD দুটি ধরনের কিউ ব্যবহার করে:
- Serial Queue: এই কিউ-তে একবারে একটি কাজ সম্পন্ন হয়। প্রতিটি কাজ একটি নির্দিষ্ট ক্রমে সম্পন্ন হয়।
- Concurrent Queue: এই কিউ-তে একাধিক কাজ একই সাথে সম্পন্ন হতে পারে। এখানে কাজগুলো একে অপরের সাথে সমান্তরালভাবে চলতে পারে।
GCD-তে আমরা প্রধানত তিনটি কিউ ব্যবহার করি:
- Main Queue: এটি মেইন থ্রেডে কাজ করে এবং UI আপডেটের জন্য ব্যবহৃত হয়। এটি একটি সিরিয়াল কিউ।
- Global Queue: এটি একটি কনকারেন্ট কিউ এবং সাধারণত ব্যাকগ্রাউন্ড টাস্ক সম্পন্ন করতে ব্যবহৃত হয়।
- Custom Queue: আপনি চাইলে নিজের কাস্টম কিউ তৈরি করে কাজ সম্পন্ন করতে পারেন।
GCD ব্যবহার: একটি সাধারণ উদাহরণ
DispatchQueue.global().async {
// ব্যাকগ্রাউন্ড কাজ
print("This is a background task.")
// মেইন থ্রেডে কাজ সম্পন্ন করা
DispatchQueue.main.async {
print("This is executed on the main thread.")
}
}
DispatchQueue.global().async: এখানে, আমরা একটি গ্লোবাল কনকারেন্ট কিউ ব্যবহার করে একটি ব্যাকগ্রাউন্ড টাস্ক চালাচ্ছি।DispatchQueue.main.async: ব্যাকগ্রাউন্ড টাস্ক শেষ হওয়ার পর, আমরা মেইন থ্রেডে কাজ সম্পন্ন করছি (যেমন UI আপডেট)।
সিরিয়াল এবং কনকারেন্ট কিউ
১. সিরিয়াল কিউ
let serialQueue = DispatchQueue(label: "com.example.serialQueue")
serialQueue.async {
for i in 1...5 {
print("Task 1 - \(i)")
}
}
serialQueue.async {
for i in 1...5 {
print("Task 2 - \(i)")
}
}
- এখানে, একটি সিরিয়াল কিউ তৈরি করা হয়েছে। এই কিউ-তে কাজগুলো একটি নির্দিষ্ট ক্রমে সম্পন্ন হয়। প্রথম কাজ শেষ না হওয়া পর্যন্ত দ্বিতীয় কাজ শুরু হয় না।
২. কনকারেন্ট কিউ
let concurrentQueue = DispatchQueue(label: "com.example.concurrentQueue", attributes: .concurrent)
concurrentQueue.async {
for i in 1...5 {
print("Task 1 - \(i)")
}
}
concurrentQueue.async {
for i in 1...5 {
print("Task 2 - \(i)")
}
}
- এখানে, একটি কনকারেন্ট কিউ তৈরি করা হয়েছে। এই কিউ-তে একাধিক কাজ একসাথে চলতে পারে এবং তারা সমান্তরালভাবে সম্পন্ন হয়।
সিঙ্ক্রোনাস এবং অ্যাসিনক্রোনাস কাজ
Swift-এ GCD-তে sync এবং async মেথড ব্যবহার করা হয় কাজগুলো সিঙ্ক্রোনাস বা অ্যাসিনক্রোনাস ভাবে সম্পন্ন করতে।
sync: এটি সিঙ্ক্রোনাস কাজ সম্পন্ন করে, অর্থাৎ কাজটি সম্পন্ন না হওয়া পর্যন্ত প্রোগ্রাম থেমে থাকে।async: এটি অ্যাসিনক্রোনাস কাজ সম্পন্ন করে, অর্থাৎ কাজটি ব্যাকগ্রাউন্ডে চলে এবং প্রোগ্রাম চলতে থাকে।
উদাহরণ: sync এবং async
let queue = DispatchQueue(label: "com.example.queue")
queue.sync {
for i in 1...5 {
print("Sync Task - \(i)")
}
}
queue.async {
for i in 1...5 {
print("Async Task - \(i)")
}
}
print("This is printed after sync task, but may appear before async task.")
syncমেথডের কারণে প্রথম কাজ সম্পন্ন না হওয়া পর্যন্ত পরবর্তী লাইন এক্সিকিউট হয় না।asyncমেথডের কারণে কাজটি ব্যাকগ্রাউন্ডে চলে, ফলে পরবর্তী লাইন এক্সিকিউট হয়।
ডিলে করা বা বিলম্বিত কাজ (Delayed Execution)
GCD ব্যবহার করে কাজগুলো নির্দিষ্ট সময় পরে সম্পন্ন করা যায়।
DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {
print("This will be printed after a delay of 2 seconds.")
}
asyncAfterমেথড ব্যবহার করে আমরা মেইন কিউ-তে একটি কাজ ২ সেকেন্ড বিলম্বে সম্পন্ন করছি।
কাজের গ্রুপ (Dispatch Group)
GCD-তে Dispatch Group ব্যবহার করে একাধিক কাজ একত্রে গ্রুপ আকারে চালানো এবং সব কাজ শেষ হওয়ার পর নির্দিষ্ট কাজ সম্পন্ন করা যায়।
let group = DispatchGroup()
let queue = DispatchQueue.global()
queue.async(group: group) {
for i in 1...3 {
print("Task 1 - \(i)")
}
}
queue.async(group: group) {
for i in 1...3 {
print("Task 2 - \(i)")
}
}
group.notify(queue: DispatchQueue.main) {
print("All tasks are completed.")
}
DispatchGroupব্যবহার করে দুটি কাজ একটি গ্রুপে সংগঠিত করা হয়েছে। সব কাজ শেষ হলেnotifyমেথড ব্যবহার করে মেইন থ্রেডে একটি কাজ সম্পন্ন করা হয়েছে।
উপসংহার
Swift-এ GCD (Grand Central Dispatch) হলো একটি শক্তিশালী কনকারেন্সি টুল, যা প্রোগ্রামকে আরও কার্যকর, দ্রুত এবং রেসপন্সিভ করে।
- সিরিয়াল এবং কনকারেন্ট কিউ ব্যবহার করে বিভিন্ন ধরনের কাজ সম্পন্ন করা যায়।
syncএবংasyncমেথড ব্যবহার করে সিঙ্ক্রোনাস এবং অ্যাসিনক্রোনাস কাজ করা যায়।- Dispatch Group এবং
asyncAfterএর মতো টুলগুলো ব্যবহার করে কাজের সমন্বয় এবং বিলম্বিত কাজ পরিচালনা করা সম্ভব।
GCD Swift-এ কনকারেন্সি এবং মাল্টিথ্রেডিং পরিচালনা করার জন্য একটি অত্যন্ত কার্যকর এবং সহজলভ্য উপায়।
Swift-এ থ্রেড এবং কিউ ব্যবহার করে অ্যাসিনক্রোনাস প্রোগ্রামিং (asynchronous programming) করা হয়, যা অ্যাপ্লিকেশনের পারফরম্যান্স উন্নত করতে এবং ব্যবহারকারীর অভিজ্ঞতা উন্নত করতে সাহায্য করে। Swift-এ থ্রেড (Thread) এবং কিউ (Queue) ব্যবহার করে আপনি একাধিক কাজ একসাথে সম্পাদন করতে পারেন, যা অ্যাপ্লিকেশনকে আরও দ্রুত এবং রেসপন্সিভ করে।
Swift-এ থ্রেড এবং কিউ (Thread and Queue)
থ্রেড (Thread)
থ্রেড হলো এক্সিকিউশনের একটি নির্দিষ্ট লাইন, যা প্রোগ্রাম বা প্রসেসের মধ্যে একক কাজ সম্পাদন করে। থ্রেড ব্যবহার করে আপনি একাধিক কাজ একসাথে বা প্যারালালে সম্পাদন করতে পারেন। তবে, থ্রেড ম্যানেজমেন্ট কিছুটা জটিল এবং এর ব্যবহারে সতর্ক থাকা প্রয়োজন, কারণ এটি ডেডলক, রেস কন্ডিশন ইত্যাদি সমস্যা সৃষ্টি করতে পারে।
থ্রেড ব্যবহারের উদাহরণ
Swift-এ থ্রেড তৈরি করতে এবং চালাতে আপনি Thread ক্লাস ব্যবহার করতে পারেন:
let myThread = Thread {
for i in 1...5 {
print("This is running in a new thread: \(i)")
}
}
myThread.start()
এখানে, myThread নামের একটি থ্রেড তৈরি করা হয়েছে, যা ১ থেকে ৫ পর্যন্ত প্রিন্ট করবে। থ্রেডটি শুরু করার জন্য start() মেথড ব্যবহার করা হয়েছে।
কিউ (Queue)
Swift-এ থ্রেড ম্যানেজমেন্টের জন্য সাধারণত গ্র্যান্ড সেন্ট্রাল ডিসপ্যাচ (GCD) ব্যবহার করা হয়, যা একটি লো-লেভেল API এবং অ্যাপল-এর মাল্টিথ্রেডিং টেকনোলজি। GCD ব্যবহার করে আপনি সিরিয়াল এবং কনকারেন্ট কিউ তৈরি করতে পারেন। GCD এর মাধ্যমে কাজ সহজ, কার্যকর, এবং নিরাপদ উপায়ে মাল্টিথ্রেডিং করা যায়।
সিরিয়াল কিউ (Serial Queue)
সিরিয়াল কিউ একটি সময়ে একটি মাত্র কাজ সম্পাদন করে। এটি কাজগুলোকে সিরিয়ালি (একটির পর একটি) চালায়। সিরিয়াল কিউ সাধারণত নির্দিষ্ট ক্রমে কাজ সম্পাদন করতে এবং ডেটা সেফটি নিশ্চিত করতে ব্যবহৃত হয়।
উদাহরণ:
let serialQueue = DispatchQueue(label: "com.example.serialQueue")
serialQueue.async {
for i in 1...5 {
print("Task 1: \(i)")
}
}
serialQueue.async {
for i in 1...5 {
print("Task 2: \(i)")
}
}
এখানে, serialQueue একটি সিরিয়াল কিউ, যেখানে প্রথমে Task 1 সম্পন্ন হবে, তারপর Task 2।
কনকারেন্ট কিউ (Concurrent Queue)
কনকারেন্ট কিউ একাধিক কাজ একসাথে সম্পাদন করে। এটি একই সময়ে একাধিক থ্রেড চালাতে পারে, যার ফলে কাজগুলো প্যারালালে চলে। কনকারেন্ট কিউ সাধারণত যখন কাজগুলো একে অপরের উপর নির্ভরশীল নয়, তখন ব্যবহার করা হয়।
উদাহরণ:
let concurrentQueue = DispatchQueue(label: "com.example.concurrentQueue", attributes: .concurrent)
concurrentQueue.async {
for i in 1...5 {
print("Task A: \(i)")
}
}
concurrentQueue.async {
for i in 1...5 {
print("Task B: \(i)")
}
}
এখানে, concurrentQueue একটি কনকারেন্ট কিউ, যেখানে Task A এবং Task B একসাথে প্যারালালে সম্পন্ন হবে।
মেইন কিউ (Main Queue)
মেইন কিউ হলো GCD-এর একটি বিশেষ কিউ, যা অ্যাপ্লিকেশনের মেইন থ্রেডে কাজ চালায়। এটি সাধারণত UI আপডেট বা অন্য মেইন থ্রেড সংক্রান্ত কাজের জন্য ব্যবহৃত হয়। সব UI সম্পর্কিত কাজ মেইন কিউতে করতে হয়, কারণ UI শুধুমাত্র মেইন থ্রেডে আপডেট করা যায়।
উদাহরণ:
DispatchQueue.main.async {
print("This is running on the main queue.")
}
এখানে, কাজটি মেইন কিউতে অ্যাসিনক্রোনাসলি চালানো হবে।
কিউ-এর ধরণ
- মেইন কিউ: মেইন থ্রেডে কাজ চালায়, UI আপডেট এবং ইন্টারফেস সম্পর্কিত কাজের জন্য।
- গ্লোবাল কিউ: GCD-এর প্রি-ডিফাইন্ড কনকারেন্ট কিউ, যা ব্যাকগ্রাউন্ডে কাজ চালানোর জন্য ব্যবহৃত হয়।
- কাস্টম সিরিয়াল/কনকারেন্ট কিউ: আপনি নিজে সিরিয়াল বা কনকারেন্ট কিউ তৈরি করতে পারেন।
sync এবং async ফাংশন
async: কাজ অ্যাসিনক্রোনাসলি (প্যারালালে) চালায়, ফলে এটি অবিলম্বে কাজ সম্পন্ন না করেও পরবর্তী কাজ চালাতে পারে।sync: কাজ সিঙ্ক্রোনাসলি চালায়, অর্থাৎ এটি সম্পন্ন না হওয়া পর্যন্ত পরবর্তী কাজ শুরু হয় না। এটি ব্লকিং অপারেশন তৈরি করতে পারে, তাই ব্যবহারে সাবধান থাকা উচিত।
let queue = DispatchQueue(label: "com.example.queue")
// Synchronous execution
queue.sync {
print("Synchronous Task")
}
// Asynchronous execution
queue.async {
print("Asynchronous Task")
}
থ্রেড এবং কিউ ব্যবহারের সময় সতর্কতা
- ডেডলক: যদি আপনি ভুলভাবে
syncব্যবহার করেন, তাহলে এটি ডেডলক সৃষ্টি করতে পারে, যা আপনার প্রোগ্রামকে স্থবির করে দিতে পারে। - রেস কন্ডিশন: একাধিক থ্রেড বা কিউ যদি একই ডেটার উপর একসাথে কাজ করে এবং তাদের মধ্যে সমন্বয় না থাকে, তাহলে ডেটা ইন্টিগ্রিটির সমস্যা হতে পারে।
- মেইন কিউতে ভারী কাজ এড়ানো: মেইন কিউতে ভারী কাজ করা উচিত নয়, কারণ এটি UI ফ্রিজিং এবং ব্যবহারকারীর অভিজ্ঞতা খারাপ করতে পারে। ভারী কাজ ব্যাকগ্রাউন্ড কিউতে চালানো উচিত।
উপসংহার
- থ্রেড: এক্সিকিউশনের নির্দিষ্ট লাইন, যা একাধিক কাজ প্যারালালে সম্পাদন করতে পারে।
- কিউ: GCD ব্যবহার করে সিরিয়াল এবং কনকারেন্ট কিউ তৈরি করা যায়, যা থ্রেড ম্যানেজমেন্টকে সহজ এবং কার্যকর করে।
- মেইন কিউ: UI আপডেটের জন্য ব্যবহৃত, এবং সমস্ত UI সম্পর্কিত কাজ মেইন কিউতে করতে হয়।
Swift-এ থ্রেড এবং কিউ ব্যবহার করে অ্যাসিনক্রোনাস প্রোগ্রামিং আরও কার্যকর, দ্রুত, এবং সংবেদনশীল করা যায়, যা অ্যাপ্লিকেশনের পারফরম্যান্স এবং ব্যবহারকারীর অভিজ্ঞতা উন্নত করে।
Swift 5.5 এবং তার পরবর্তী সংস্করণগুলোতে async এবং await ব্যবহার করে কনকারেন্ট কোড লেখা সহজ এবং পাঠযোগ্য করা হয়েছে। এটি অ্যাসিনক্রোনাস কাজগুলিকে আরও সহজভাবে ম্যানেজ করতে দেয়, যেখানে কোড সিঙ্ক্রোনাসের মতোই দেখায়।
async এবং await কী?
async: ফাংশনের সংজ্ঞায়asyncকীওয়ার্ড ব্যবহার করে এটি নির্দেশ করা হয় যে ফাংশনটি অ্যাসিনক্রোনাস। এটি টাস্ক সম্পন্ন করতে সময় নেয় এবং অন্য ফাংশনকেawaitব্যবহার করে এটি কল করতে হয়।await:awaitকীওয়ার্ড ব্যবহার করেasyncফাংশনের কাজ শেষ হওয়া পর্যন্ত অপেক্ষা করা হয়।
উদাহরণ: async এবং await ব্যবহার
import Foundation
func fetchData() async -> String {
// কিছু ডেটা ফেচ করা হচ্ছে, যা অ্যাসিনক্রোনাস হতে পারে
return "Data fetched"
}
func processData() async {
let data = await fetchData()
print(data)
}
// Task-এ async কাজ চালানো হচ্ছে
Task {
await processData()
}
fetchDataএকটি অ্যাসিনক্রোনাস ফাংশন যা ডেটা রিটার্ন করে।processDataফাংশনawaitব্যবহার করেfetchDataফাংশনের কাজ শেষ হওয়া পর্যন্ত অপেক্ষা করে এবং তারপর প্রিন্ট করে।
async এবং await এর সুবিধা
- সহজ পঠনযোগ্য কোড: অ্যাসিনক্রোনাস কাজগুলো সিঙ্ক্রোনাস কোডের মতোই দেখতে হয়, যা কোডকে আরও ক্লিন এবং সহজপাঠ্য করে।
- ডেটা হ্যান্ডলিং: ডেটা ফেচিং বা API কলের মতো অ্যাসিনক্রোনাস কাজগুলি সঠিকভাবে পরিচালিত হয়।
- কনকারেন্সি সহজ করা: কনকারেন্ট কাজের সময় থ্রেড ম্যানেজমেন্ট বা কমপ্লেক্স কনকারেন্ট কোডিং কৌশল ব্যবহার না করেও কাজ করা যায়।
ব্যবহারিক উদাহরণ: API কল
import Foundation
func fetchWeatherData() async throws -> String {
let url = URL(string: "https://api.weather.com/data")!
let (data, _) = try await URLSession.shared.data(from: url)
return String(data: data, encoding: .utf8) ?? "No data"
}
Task {
do {
let weatherData = try await fetchWeatherData()
print(weatherData)
} catch {
print("Error fetching data: \(error)")
}
}
- এখানে,
fetchWeatherDataAPI থেকে ডেটা ফেচ করে, যা একটি অ্যাসিনক্রোনাস ফাংশন। awaitএবংtryব্যবহার করে এটি চালানো হচ্ছে, এবং ডেটা ফেচ হওয়ার পর সেটি প্রিন্ট করা হচ্ছে।
সংক্ষেপে
Swift-এ async এবং await ব্যবহার করে অ্যাসিনক্রোনাস কোড লেখা সহজ এবং কার্যকরী। এটি ফাংশনাল প্রোগ্রামিং এবং কনকারেন্ট প্রোগ্রামিং-এর জন্য একটি শক্তিশালী টুল, যা কোডকে দ্রুত, সহজ এবং সুগঠিত করে তোলে।
Read more