البرمجة غير المتزامنة في Rust: دليل شامل للمبتدئين
\n\nالبرمجة غير المتزامنة هي نموذج يسمح بتنفيذ مهام متعددة في وقت واحد دون حظر تيار التنفيذ الرئيسي. في Rust، يتم تحقيق عدم التزامن من خلال الكلمات المفتاحية async و .await، بالإضافة إلى بيئة تشغيل قوية مثل Tokio. سيساعدك هذا الدليل على فهم أساسيات البرمجة غير المتزامنة في Rust، حتى لو كنت في بداية رحلتك.
ما هي البرمجة غير المتزامنة ولماذا نحتاجها؟
\n\nفي الكود المتزامن التقليدي، يتم تنفيذ كل عملية بشكل تسلسلي. إذا قام البرنامج بطلب HTTP، فإنه ينتظر الرد دون فعل أي شيء. في النهج غير المتزامن، يمكن للبرنامج بدء الطلب والتبديل إلى مهمة أخرى أثناء انتظار الرد. هذا مهم بشكل خاص لـ:
\n\n- \n
- تطبيقات الشبكات — خوادم الويب، عملاء API، غرف الدردشة. \n
- العمل مع الملفات — قراءة/كتابة كميات كبيرة من البيانات. \n
- واجهات المستخدم — لمنع تجميد الواجهة أثناء العمليات الخلفية. \n
يقدم Rust تكلفة صفرية للتجريد: يتم تجميع الكود غير المتزامن إلى تعليمات آلية فعالة. على عكس اللغات الأخرى حيث قد يكون عدم التزامن "مكلفًا"، يسمح Rust بكتابة برامج غير متزامنة سريعة وآمنة.
\n\nأساسيات async/await في Rust
\n\nالكلمات المفتاحية async و .await هي أساس البرمجة غير المتزامنة في Rust. دعنا نشرحها بمثال بسيط.
1. إنشاء دالة غير متزامنة
\n\nيمكن لأي دالة أن تصبح غير متزامنة بإضافة الكلمة المفتاحية async قبلها. هذه الدالة تُرجع Future — قيمة ليست جاهزة بعد، ولكنها ستكون جاهزة في المستقبل.
// دالة متزامنة\nfn say_hello_sync() -> String {\n String::from("Hello, World!")\n}\n\n// دالة غير متزامنة\nasync fn say_hello_async() -> String {\n String::from("Hello, World!")\n}\n\nلاحظ: إذا قمت فقط باستدعاء say_hello_async()، فإن الكود لن يتم تنفيذه. ستحصل على كائن Future يحتاج إلى "تشغيل" باستخدام بيئة التشغيل.
2. انتظار النتيجة باستخدام .await
\n\nللحصول على القيمة من Future، استخدم .await. تخبر هذه الكلمة المفتاحية المترجم: "أوقف تنفيذ هذه الدالة مؤقتًا حتى يصبح Future جاهزًا، واترك المهام الأخرى تعمل".
async fn process() {\n let result = say_hello_async().await;\n println!("{}", result);\n}\n\n3. الكتل غير المتزامنة
\n\nيمكنك أيضًا إنشاء كتل كود غير متزامنة "على الطاير":
\n\nlet future = async {\n let x = 10;\n let y = 20;\n x + y\n};\n\nlet result = future.await; // النتيجة: 30\n\nبيئة التشغيل: Tokio — قلب Rust غير المتزامن
\n\nبمفردها، لا تقوم async و .await بتشغيل الكود. نحتاج إلى بيئة تشغيل — بيئة تنفيذ تدير المهام وجدولة التشغيل. المكتبة الأكثر شيوعًا لذلك هي Tokio.
تثبيت Tokio
\n\nأضف إلى Cargo.toml:
[dependencies]\ntokio = { version = "1.0", features = ["full"] }\n\nأول مشروع غير متزامن
\n\nلتشغيل الكود غير المتزامن، استخدم الماكرو #[tokio::main]. يقوم تلقائيًا بإنشاء بيئة التشغيل وتشغيل الدالة الخاصة بك.
use tokio;\n\n#[tokio::main]\nasync fn main() {\n println!("نقوم بتشغيل الكود غير المتزامن!");\n let result = say_hello_async().await;\n println!("النتيجة: {}", result);\n}\n\nasync fn say_hello_async() -> String {\n // محاكاة عملية طويلة\n tokio::time::sleep(tokio::time::Duration::from_secs(2)).await;\n String::from("Hello, Async Wo