Rust-এ Futures এবং Tasks আসলে অ্যাসিঙ্ক্রোনাস প্রোগ্রামিং (asynchronous programming) এর মূল অংশ। এগুলি আপনাকে কোডের একাধিক অংশকে একসাথে কার্যকর করতে সাহায্য করে, বিশেষ করে যখন কিছু কাজ অপেক্ষা করার জন্য (যেমন নেটওয়ার্ক কল, ফাইল সিস্টেম অপারেশন, বা অন্য কোনো IO অপারেশন) সময় নেয়।
- Future: এটি একটি মানের প্রতিনিধিত্ব যা এখনো প্রস্তুত হয়নি কিন্তু ভবিষ্যতে হবে।
- Task: এটি আসলে একটি অ্যাসিঙ্ক্রোনাস কাজ যা রান হচ্ছে এবং যার একটি ভবিষ্যত মান (future) হতে পারে।
এগুলো প্রধানত অ্যাসিঙ্ক্রোনাস এবং কনকারেন্ট প্রোগ্রামিংয়ে ব্যবহৃত হয়, যেখানে বিভিন্ন কাজ একসাথে সম্পাদিত হয়।
Future-এর ধারণা
Future হল একটি ডেটা স্ট্রাকচার যা একটি পরবর্তী মান ধারণ করে, যেটি ভবিষ্যতে প্রাপ্ত হবে। অ্যাসিঙ্ক্রোনাস কোডে, ফাংশনগুলি সাধারণত Future রিটার্ন করে। আপনি যখন await ব্যবহার করেন, তখন এটি অপেক্ষা করে যে Future সম্পন্ন হবে এবং তার পরে মানটি ফেরত আসবে।
উদাহরণ:
use std::future::Future;
async fn add(a: i32, b: i32) -> i32 {
a + b
}
fn main() {
let future = add(5, 3); // Future তৈরি হচ্ছে
println!("Result: {}", futures::executor::block_on(future)); // Future await করা
}এখানে, add ফাংশনটি একটি Future রিটার্ন করছে, যা অ্যাসিঙ্ক্রোনাসভাবে a এবং b যোগফল হিসাব করে। futures::executor::block_on() ফাংশন ব্যবহার করা হয়েছে যাতে Future রেজাল্টে ওয়েট করা যায় এবং তারপরে ফলাফল পাওয়া যায়।
Futures এবং Tasks এর মধ্যে সম্পর্ক
Future একটি আসন্ন মানকে প্রতিনিধিত্ব করে, কিন্তু এটি নিজে কিছু কাজ করতে পারে না যতক্ষণ না তা poll করা হয়। Task হল একটি কাজ যা একটি Future তৈরি করে এবং এটি চালানো শুরু করে। Task কে স্পন করা এবং চালানো মূলত executor বা অন্য কোনো টাস্ক রানার দ্বারা করা হয়।
Tasks এগুলিই আসলে অ্যাসিঙ্ক্রোনাস কাজ চালায়। Rust-এ অ্যাসিঙ্ক্রোনাস ফাংশনগুলি সাধারণত Future টাইপ রিটার্ন করে, এবং সেই Future কে task::spawn বা block_on ব্যবহার করে রান করা হয়।
Task উদাহরণ:
use tokio; // Tokio crate ব্যবহৃত হচ্ছে
use tokio::task;
async fn example_task() {
println!("Task is running!");
}
#[tokio::main]
async fn main() {
let task = task::spawn(example_task());
task.await.unwrap(); // Task রান করা এবং অপেক্ষা করা
}এখানে, task::spawn ব্যবহৃত হয়েছে example_task রান করার জন্য, এবং task.await.unwrap() এর মাধ্যমে আমরা নিশ্চিত করছি যে টাস্কটি শেষ হয়ে যাবে এবং ত্রুটি থাকলে সেটা হ্যান্ডেল করা হবে।
await এবং block_on ব্যবহারের পার্থক্য
await:asyncফাংশন বা ফিউচারের জন্য ব্যবহৃত হয়, যা অ্যাসিঙ্ক্রোনাসভাবে কাজ করার সময় কাজের ফলাফল ফেরত নিয়ে আসে।block_on: এটি অ্যাসিঙ্ক্রোনাস কোডকে সিঙ্ক্রোনাস করে ফেলে, অর্থাৎ অ্যাসিঙ্ক্রোনাস কাজ শেষ না হওয়া পর্যন্ত অন্যান্য কোড চলতে পারে না।
await উদাহরণ:
async fn do_work() -> i32 {
42
}
fn main() {
let result = tokio::runtime::Runtime::new().unwrap().block_on(do_work());
println!("Result: {}", result);
}এখানে block_on ব্যবহার করে অ্যাসিঙ্ক্রোনাস do_work() ফাংশনটি ব্লক করা হয়েছে এবং তার ফলাফল পেতে আমরা অপেক্ষা করছি।
Futures এবং Tasks-এর অ্যাসিঙ্ক্রোনাস কাজের মধ্যে পার্থক্য
- Futures: এটি একটি মান ধারণ করে যা পরবর্তীতে আসবে। এটি শুধু একবার কাজ করবে এবং পরে অন্য কোনো কাজের জন্য প্রতিক্রিয়া করবে।
- Tasks: এটি আসলে একটি রানিং ইউনিট, যা
Futureকে চালিয়ে একটি মানের জন্য অপেক্ষা করে এবং সেই মানে পৌঁছানোর পর কাজ শেষ হয়ে যায়।
Tokio এবং async-std
Rust-এ Futures এবং Tasks ব্যবস্থাপনা করার জন্য বেশ কিছু লাইব্রেরি রয়েছে, যার মধ্যে Tokio এবং async-std অন্যতম।
Tokio উদাহরণ:
Tokio হল Rust-এর একটি অ্যাসিঙ্ক্রোনাস রানটাইম যা ফিউচার এবং টাস্কগুলোকে ম্যানেজ করতে ব্যবহৃত হয়।
[dependencies]
tokio = { version = "1", features = ["full"] }use tokio;
async fn greet() {
println!("Hello from Tokio!");
}
#[tokio::main]
async fn main() {
greet().await;
}এখানে, #[tokio::main] অ্যাট্রিবিউটটি ব্যবহৃত হয়েছে, যা অ্যাসিঙ্ক্রোনাস টাস্ক চালানোর জন্য tokio::runtime::Runtime ব্যবহার করে।
সারাংশ
Futures এবং Tasks Rust-এ অ্যাসিঙ্ক্রোনাস প্রোগ্রামিংয়ের দুটি গুরুত্বপূর্ণ অংশ। Futures হল মান যা ভবিষ্যতে পাওয়া যাবে, এবং Tasks হল সেই অ্যাসিঙ্ক্রোনাস কাজ যা একটি Future তৈরি করে এবং তার উপর কাজ করে। async এবং await ব্যবহারের মাধ্যমে অ্যাসিঙ্ক্রোনাস কোড রান করা হয়, এবং block_on ব্যবহার করে অ্যাসিঙ্ক্রোনাস কাজগুলো সিঙ্ক্রোনাসভাবে সম্পন্ন করা যায়। Tokio এবং async-std হল প্রধান লাইব্রেরি যা Rust-এ Futures এবং Tasks পরিচালনার জন্য ব্যবহৃত হয়।
Read more