parking_lot في Rust: دليل شامل مع أمثلة عملية

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

parking_lot في Rust: أدوات مزامنة فائقة السرعة

مكتبة parking_lot هي واحدة من أشهر وأسرع تطبيقات أدوات المزامنة (synchronization primitives) للغة Rust. توفر بديلاً للأدوات القياسية مثل std::sync::Mutex و std::sync::RwLock و std::sync::Condvar، لكن بأداء أفضل بشكل ملحوظ وحجم كود أصغر.

لماذا تحتاج هذه المكتبة؟ أدوات المزامنة القياسية في Rust، رغم أمانها، تعاني من بعض العيوب: فهي تستخدم استدعاءات النظام (مثل futex في Linux) حتى في السيناريوهات البسيطة، وتتطلب ذاكرة إضافية للعلامات، ولها بنية داخلية أكثر تعقيدًا. تحل parking_lot هذه المشكلات باستخدام خوارزميات أكثر كفاءة (مثل الأقفال المتفائلة وحلقات الدوران) وتقليل التكاليف الإضافية. والنتيجة هي كود أسرع، خاصة في التطبيقات متعددة الخيوط ذات المنافسة العالية.

المكتبة متوافقة تمامًا مع Rust ولا تتطلب كودًا غير آمن (unsafe) من المستخدم. تقدم نفس الواجهات التي تقدمها المكتبة القياسية، ولكن مع ميزات إضافية: Mutex مع دعم المهلات الزمنية، RwLock بطابور عادل، Once للتهيئة البطيئة، و ReentrantMutex للأقفال القابلة لإعادة الدخول. تعتبر parking_lot المعيار الفعلي لتطبيقات Rust عالية الأداء، من خوادم الويب إلى محركات الألعاب.

التثبيت

أضف المكتبة إلى ملف Cargo.toml لمشروعك:

[dependencies]
parking_lot = "0.12"

ثم نفّذ الأمر التالي:

cargo build

أو، إذا كنت تستخدم cargo add (منذ Rust 1.62):

cargo add parking_lot

بعد ذلك، يمكنك استيراد الأدوات من المكتبة:

use parking_lot::{Mutex, RwLock, Condvar, Once, ReentrantMutex};

بداية سريعة: مثال عملي بسيط

إليك مثال بسيط لاستخدام Mutex من parking_lot لحماية عداد مشترك في بيئة متعددة الخيوط:

use parking_lot::Mutex;
use std::thread;

fn main() {
    // إنشاء كائن Mutex يغلّف قيمة
    let counter = Mutex::new(0);

    // إنشاء 10 خيوط، كل منها يزيد العداد بمقدار 1
    let mut handles = vec![];
    for _ in 0..10 {
        let handle = thread::spawn(|| {
            // الحصول على القفل — .lock() يُرجع حارس RAII
            let mut guard = counter.lock();
            *guard += 1;
            // يتم تحرير الحارس تلقائيًا عند الخروج من النطاق
        });
        handles.push(handle);
    }

    // انتظار انتهاء جميع الخيوط
    for handle in handles {
        handle.join().unwrap();
    }

    // قراءة القيمة النهائية
    let final_value = *counter.lock();
    println!("القيمة النهائية: {}", final_value); // يجب أن تكون 10
}

في هذا المثال، counter.lock() يُرجع MutexGuard الذي يحرر القفل تلقائيًا عند تدميره. على عكس std::sync::Mutex القياسي، لا تحتاج هنا لمعالجة أخطاء التسميم (poisoning) — فـ parking_lot لا تسمم القفل افتراضيًا عند حدوث panic.

أهم الدوال والأنواع

فيما يلي 8 دوال/أنواع رئيسية من مكتبة parking_lot مع التوقيع والوصف والأمثلة.

1. Mutex::lock()

التوقيع: pub fn lock(&self) -> MutexGuard<'_, T>

الوصف: يلتقط القفل (mutex)، مما يمنع الخيط الحالي حتى يتم الحصول على القفل. يُرجع حارس RAII الذي يحرر القفل تلقائيًا عند الخروج من النطاق.

use pa                    

توصيات