بناء تطبيقات غير متزامنة باستخدام Tokio
استخدموا بيئة تشغيل Tokio لتنفيذ المهام غير المتزامنة بكفاءة، ومعالجة عمليات الإدخال والإخراج وغيرها من العمليات المتزامنة.
بناء تطبيقات غير متزامنة باستخدام Tokio درس مجاني في Learn Rust Coding على CoddyKit. هذا هو الدرس 2 من أصل 3. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Learn Rust Coding، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Learn Rust Coding 3 دروس في المجموع.
التعرّف إلى بيئة تشغيل Tokio
مرحبًا بعودتك! في الدرس السابق، تعلمت عن async وawait. لكن كيف تعمل دالة async فعليًا؟
هنا يأتي دور بيئة تشغيل غير متزامنة مثل Tokio. فـTokio مكتبة قوية توفر بيئة التنفيذ اللازمة لتعليمات Rust البرمجية غير المتزامنة.
- تجدول قيم
Futureوتنفذها. - تتعامل مع عمليات الإدخال والإخراج غير الحاجزة.
- تدير المهام المتزامنة بكفاءة.
تشغيل تعليماتك البرمجية غير المتزامنة
للبدء باستخدام Tokio، تستخدم عادةً ماكرو السمة #[tokio::main]. يحوّل هذا الماكرو async fn main() إلى fn main() عادية تهيّئ بيئة تشغيل Tokio وتشغّل تعليماتك البرمجية غير المتزامنة.
فكّر فيه بوصفه نقطة الدخول إلى تطبيقك غير المتزامن.
use tokio;
#[tokio::main]
async fn main() {
println!("Hello from Tokio!");
}إنشاء مهام غير متزامنة جديدة
من الميزات الأساسية في Tokio القدرة على تشغيل عمليات غير متزامنة متعددة بالتزامن. يمكنك تحقيق ذلك باستخدام tokio::spawn.
تستقبل tokio::spawn قيمة من النوع Future وتجدولها للتشغيل على بيئة تشغيل Tokio. ويتيح ذلك لمهمتك الرئيسية مواصلة التنفيذ بينما تعمل المهمة المنشأة في الخلفية.
- لا تحظر التنفيذ.
- تُرجع
JoinHandleلانتظار اكتمالها. - تعمل المهام بشكل مستقل.
<code>tokio::spawn</code> عمليًا
لنرَ كيف تتيح لك tokio::spawn تنفيذ التعليمات البرمجية بالتزامن. لاحظ ظهور الرسالتين، لكن قد تُطبع رسالة «done» قبل رسالة «task complete» بسبب عملية السكون.
use tokio::time::{sleep, Duration};
#[tokio::main]
async fn main() {
// Spawn a new task
let handle = tokio::spawn(async {
sleep(Duration::from_secs(1)).await;
println!("Async task complete!");
});
println!("Main task continuing...");
// Wait for the spawned task to finish
handle.await.unwrap();
println!("All tasks done.");
}انتظار مهام متعددة
عندما تكون لديك مهام متعددة، فغالبًا ما تحتاج إلى انتظار اكتمالها جميعًا. توفر Tokio ماكرو tokio::join! لهذا الغرض.
تتيح لك tokio::join! انتظار Futures متعددة بالتزامن ودمج نتائجها. وهي تشبه انتظار عدة JoinHandle باستخدام `await`، لكنها غالبًا أكثر اختصارًا مع مجموعات Futures الثابتة.
use tokio::time::{sleep, Duration};
#[tokio::main]
async fn main() {
let task1 = async {
sleep(Duration::from_secs(1)).await;
println!("Task 1 finished");
1
};
let task2 = async {
sleep(Duration::from_millis(500)).await;
println!("Task 2 finished");
2
};
let (result1, result2) = tokio::join!(task1, task2);
println!("Results: {}, {}", result1, result2);
}إدخال وإخراج الملفات غير المتزامن باستخدام Tokio
يمكن لعمليات الملفات التقليدية أن تحظر الخيط، وهذا سيئ للتطبيقات غير المتزامنة. توفر وحدة tokio::fs في Tokio إصدارات غير متزامنة من عمليات نظام الملفات.
يتيح ذلك لتطبيقك البقاء سريع الاستجابة حتى عند قراءة ملفات كبيرة أو تنفيذ عمليات ملفات كثيرة، إذ تتم معالجة الإدخال والإخراج بطريقة غير حاجزة.
tokio::fs::read_to_stringtokio::fs::writetokio::fs::Fileلمزيد من التحكم
قراءة ملف بطريقة غير متزامنة
إليك كيفية قراءة ملف بطريقة غير متزامنة باستخدام tokio::fs::read_to_string. لكي تعمل هذه التعليمات البرمجية، تأكد من وجود ملف باسم hello.txt في المجلد نفسه الذي يوجد فيه مشروع Rust (مثلًا داخل src/ أو في جذر المشروع)، وأن يحتوي على بعض المحتوى.
use tokio::fs;
#[tokio::main]
async fn main() {
let path = "hello.txt";
// Create a dummy file for the example if it doesn't exist
// In a real app, you'd handle file creation/existence more robustly
if let Err(_) = fs::metadata(path).await {
fs::write(path, "Hello, Tokio file!").await.unwrap();
}
match fs::read_to_string(path).await {
Ok(content) => println!("File content: '{}'", content),
Err(e) => eprintln!("Error reading file: {}", e),
}
}عمليات الشبكة غير المتزامنة
تتألق Tokio حقًا في برمجة الشبكات. إذ توفر وحدتها tokio::net بدائيات غير حاجزة للاتصال عبر TCP وUDP.
وهذا أمر بالغ الأهمية لبناء خوادم أو عملاء عالية الأداء يمكنهم التعامل مع اتصالات كثيرة في الوقت نفسه دون تخصيص خيط لكل اتصال.
tokio::net::TcpListenerللخوادم.tokio::net::TcpStreamلاتصالات العملاء.
البنية الأساسية لخادم TCP غير متزامن
رغم أن الخادم الكامل معقد، يوضح هذا المقتطف الحلقة الأساسية لخادم TCP غير متزامن باستخدام Tokio. فهو يستمع إلى الاتصالات الواردة ويطبع رسالة لكل اتصال. جرّب تشغيله، ثم افتح متصفحك على http://127.0.0.1:8080 لرؤية الاتصالات.
use tokio::net::TcpListener;
#[tokio::main]
async fn main() {
let listener = TcpListener::bind("127.0.0.1:8080").await.unwrap();
println!("Listening on: {}", listener.local_addr().unwrap());
loop {
let (socket, addr) = listener.accept().await.unwrap();
println!("Accepted connection from: {}", addr);
// In a real server, you'd spawn a task to handle the socket
// tokio::spawn(async move { handle_connection(socket).await; });
}
}
// fn handle_connection(socket: TcpStream) { /* ... */ } // Placeholderتحدي مهام Tokio
تأمل تعليمات Rust البرمجية التالية باستخدام Tokio. ما الرسالة *الأولى* التي ستُطبع في وحدة التحكم عند تشغيل هذا البرنامج؟
use tokio::time::{sleep, Duration};
#[tokio::main]
async fn main() {
tokio::spawn(async {
sleep(Duration::from_millis(200)).await;
println!("Task 1: Done");
});
tokio::spawn(async {
sleep(Duration::from_millis(100)).await;
println!("Task 2: Done");
});
println!("Main: Starting tasks...");
sleep(Duration::from_millis(300)).await;
println!("Main: Finishing.");
}مراجعة: البناء باستخدام Tokio
لقد قطعت خطوة مهمة في بناء تطبيقات غير متزامنة باستخدام Rust وTokio!
- تعمل Tokio بوصفها بيئة التشغيل غير المتزامنة التي تنفذ تعليماتك البرمجية
async. - تُعد
#[tokio::main]نقطة الدخول غير المتزامنة إلى برنامجك. - تتيح لك
tokio::spawnتشغيل مهام متعددة بالتزامن. - تساعدك
tokio::join!على انتظار Futures متعددة. - توفر Tokio إدخالًا وإخراجًا غير حاجزين للملفات (
tokio::fs) والشبكات (tokio::net).
تُعد هذه الأدوات أساسية لإنشاء تطبيقات Rust عالية التزامن وسريعة الاستجابة. واصل التدريب!
الأسئلة الشائعة
هل درس «بناء تطبيقات غير متزامنة باستخدام Tokio» مجاني؟
نعم — نص درس «بناء تطبيقات غير متزامنة باستخدام Tokio» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Learn Rust Coding، انتقل إلى CoddyKit PRO. تتضمن دورة Learn Rust Coding 3 دروس في المجموع.
ماذا ستتعلم في «بناء تطبيقات غير متزامنة باستخدام Tokio»؟
استخدموا بيئة تشغيل Tokio لتنفيذ المهام غير المتزامنة بكفاءة، ومعالجة عمليات الإدخال والإخراج وغيرها من العمليات المتزامنة. تتمرن على Learn Rust Coding مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ Learn Rust Coding؟
لا تُشترط خبرة سابقة. Learn Rust Coding على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 2 من أصل 3.
كم من الوقت يستغرق درس «بناء تطبيقات غير متزامنة باستخدام Tokio»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس Learn Rust Coding هذا؟
نعم. كل درس في Learn Rust Coding يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- مقدمة إلى Async/Await
- بناء تطبيقات غير متزامنة باستخدام Tokio
- التعامل مع Futures والمهام