Scroll to navigation

pthread_mutex_init(3) Library Functions Manual pthread_mutex_init(3)

الاسم

pthread_mutex_init, pthread_mutex_lock, pthread_mutex_trylock, pthread_mutex_unlock, pthread_mutex_destroy - عمليات على كائنات الاستبعاد المتبادل

موجز

#include <pthread.h>
pthread_mutex_t fastmutex = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t recmutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
pthread_mutex_t errchkmutex = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP;
int pthread_mutex_init(pthread_mutex_t *mutex,
                       const pthread_mutexattr_t *mutexattr);
int pthread_mutex_lock(pthread_mutex_t *mutex);
int pthread_mutex_trylock(pthread_mutex_t *mutex);
int pthread_mutex_unlock(pthread_mutex_t *mutex);
int pthread_mutex_destroy(pthread_mutex_t *mutex);

الوصف

كائن الاستبعاد المتبادل هو أداة استبعاد متبادل، وهو مفيد لحماية هياكل البيانات المشتركة من التعديلات المتزامنة، وتنفيذ المقاطع الحرجة والمراقبين.

لكائن الاستبعاد المتبادل حالتان محتملتان: غير مقفل (لا يملكه أي خيط)، ومقفل (يملكه خيط واحد). لا يمكن أبدًا أن يملك خيطان مختلفان كائن الاستبعاد المتبادل في وقت واحد. يُعلّق الخيط الذي يحاول قفل كائن استبعاد متبادل مقفل بالفعل بواسطة خيط آخر حتى يقوم الخيط المالك بفتح قفل كائن الاستبعاد المتبادل أولاً.

pthread_mutex_init يُهيئ كائن المِفصل المشار إليه بواسطة mutex وفقاً لسمات المِفصل المحددة في mutexattr. إذا كان mutexattr هو NULL، تُستخدم السمات المبدئية بدلاً من ذلك.

يدعم تطبيق LinuxThreads سمة مِفصل واحدة فقط، وهي نوع المِفصل، والتي تكون إما "سريع" أو "تكراري" أو "فحص الأخطاء". يحدد نوع المِفصل ما إذا كان يمكن قفله مرة أخرى بواسطة خيط يملكه بالفعل. النوع المبدئي هو "سريع". راجع pthread_mutexattr_init(3) لمزيد من المعلومات حول سمات المِفصل.

يمكن أيضاً تهيئة متغيرات من النوع pthread_mutex_t بشكل ثابت، باستخدام الثوابت PTHREAD_MUTEX_INITIALIZER (للمفاصل السريعة)، و PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP (للمفاصل التكرارية)، و PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP (لمفاصل فحص الأخطاء).

pthread_mutex_lock يقفل المِفصل المُعطى. إذا كان المِفصل غير مقفل حالياً، يصبح مقفلاً ويملكه الخيط المستدعي، وتُرجع pthread_mutex_lock فوراً. إذا كان المِفصل مقفلاً بالفعل بواسطة خيط آخر، تُعلق pthread_mutex_lock الخيط المستدعي حتى يُقفل المِفصل.

إذا كان المِفصل مقفلاً بالفعل بواسطة الخيط المستدعي، يعتمد سلوك pthread_mutex_lock على نوع المِفصل. إذا كان المِفصل من النوع "السريع"، يُعلق الخيط المستدعي حتى يُقفل المِفصل، مما يتسبب فعلياً في توقف الخيط المستدعي. إذا كان المِفصل من النوع "فحص الأخطاء"، تُرجع pthread_mutex_lock فوراً مع كود الخطأ EDEADLK. إذا كان المِفصل من النوع "التكراري"، تنجح pthread_mutex_lock وتُرجع فوراً، مسجلة عدد المرات التي قفل فيها الخيط المستدعي المِفصل. يجب تنفيذ عدد مساوٍ من عمليات pthread_mutex_unlock قبل أن يعود المِفصل إلى الحالة غير المقفلة.

يتصرف pthread_mutex_trylock بشكل مماثل لـ pthread_mutex_lock، باستثناء أنه لا يحظر الخيط المستدعي إذا كان المِفصل مقفلاً بالفعل بواسطة خيط آخر (أو بواسطة الخيط المستدعي في حالة المِفصل "السريع"). بدلاً من ذلك، تُرجع pthread_mutex_trylock فوراً مع كود الخطأ EBUSY.

pthread_mutex_unlock يُقفل المِفصل المُعطى. يُفترض أن المِفصل مقفل ويملكه الخيط المستدعي عند الدخول إلى pthread_mutex_unlock. إذا كان المِفصل من النوع "السريع"، يُعيده pthread_mutex_unlock دائماً إلى الحالة غير المقفلة. إذا كان من النوع "التكراري"، يُقلل عدد قفل المِفصل (عدد عمليات pthread_mutex_lock التي نفذها الخيط المستدعي عليه)، وفقط عندما يصل هذا العدد إلى الصفر يُقفل المِفصل فعلياً.

على مفاصل "فحص الأخطاء" و"التكرارية"، يتحقق pthread_mutex_unlock فعلياً في وقت التشغيل من أن المِفصل مقفل عند الدخول، وأنه قُفل بواسطة نفس الخيط الذي يستدعي الآن pthread_mutex_unlock. إذا لم تتحقق هذه الشروط، يُرجع كود خطأ ويبقى المِفصل دون تغيير. لا تقوم المفاصل "السريعة" بمثل هذه الفحوصات، مما يسمح بإقفال مِفصل مقفل بواسطة خيط غير مالكه. هذا سلوك غير محمول ويجب عدم الاعتماد عليه.

pthread_mutex_destroy يُدمر كائن المِفصل، محرراً الموارد التي قد يحملها. يجب أن يكون المِفصل غير مقفل عند الدخول. في تطبيق LinuxThreads، لا توجد موارد مرتبطة بكائنات المِفصل، وبالتالي لا يفعل pthread_mutex_destroy شيئاً في الواقع سوى التحقق من أن المِفصل غير مقفل.

إلغاء

لا تُعد أي من دوال المزامنة (mutex) نقطة إلغاء، ولا حتى pthread_mutex_lock، رغم قدرتها على تعليق خيط لفترات زمنية عشوائية. بهذه الطريقة، تكون حالة المزامنات عند نقاط الإلغاء قابلة للتوقع، مما يسمح لمعالجات الإلغاء بفتح قفل تلك المزامنات التي تحتاج إلى فتح قفلها بدقة قبل توقف الخيط عن التنفيذ. وبالتالي، يجب على الخيوط التي تستخدم الإلغاء المؤجل ألا تمسك بمزامنة لفترات زمنية طويلة.

سلامة الإشارة غير المتزامنة

دوال المزامنة ليست آمنة للإشارات غير المتزامنة. معنى هذا أنه لا ينبغي استدعاؤها من معالج إشارة. على وجه الخصوص، قد يؤدي استدعاء pthread_mutex_lock أو pthread_mutex_unlock من معالج إشارة إلى تعطيل الخيط المستدعي (deadlock).

قيمة الإرجاع

تُرجع pthread_mutex_init دائمًا 0. تُرجع دوال المزامنة الأخرى 0 عند النجاح ورمز خطأ غير صفري عند الخطأ.

الأخطاء

تُرجع الدالة pthread_mutex_lock رمز الخطأ التالي عند الخطأ:

لم تتم تهيئة كائن الاستبعاد المتبادل بشكل صحيح.
المزامنة مقفلة بالفعل بواسطة الخيط المستدعي (لمزامنات "فحص الأخطاء" فقط).

تُرجع الدالة pthread_mutex_trylock رموز الخطأ التالية عند الخطأ:

تعذر الحصول على المِفصل لأنه كان مقفلاً حالياً.
لم تتم تهيئة كائن الاستبعاد المتبادل بشكل صحيح.

تُرجع الدالة pthread_mutex_unlock رمز الخطأ التالي عند الخطأ:

لم تتم تهيئة كائن الاستبعاد المتبادل بشكل صحيح.
الخيط المستدعي لا يملك المزامنة (لمزامنات "فحص الأخطاء" فقط).

تُرجع الدالة pthread_mutex_destroy رمز الخطأ التالي عند الخطأ:

المِفصل مقفل حالياً.

انظر أيضًا

pthread_mutexattr_init(3)، pthread_mutexattr_setkind_np(3)، pthread_cancel(3).

مثال

يمكن حماية متغير عام مشترك x بواسطة مِفصل كما يلي:

int x; pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;

يجب وضع جميع الوصولات والتعديلات على x بين استدعاءات pthread_mutex_lock و pthread_mutex_unlock كما يلي:

pthread_mutex_lock(&mut); /* operate on x */ pthread_mutex_unlock(&mut);

ترجمة

تُرجمت هذه الصفحة من الدليل بواسطة زايد السعيدي <zayed.alsaidi@gmail.com>

هذه الترجمة هي وثيقة مجانية؛ راجع رخصة جنو العامة الإصدار 3 أو ما بعده للاطلاع على شروط حقوق النشر. لا توجد أي ضمانات.

إذا وجدت أي أخطاء في ترجمة صفحة الدليل هذه، يرجى إرسال بريد إلكتروني إلى قائمة بريد المترجمين: kde-l10n-ar@kde.org.

16 يونيو 2024 صفحات دليل لينكس 6.9.1