table of contents
- trixie-backports 4.31.0-1~bpo13+1
- testing 4.31.0-1
- unstable 4.31.0-1
| pthread_cond_init(3) | Library Functions Manual | pthread_cond_init(3) |
الاسم¶
pthread_cond_init, pthread_cond_signal, pthread_cond_broadcast, pthread_cond_wait, pthread_cond_timedwait, pthread_cond_destroy - عمليات على الشروط
موجز¶
#include <pthread.h>
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
int pthread_cond_init(pthread_cond_t *cond,
pthread_condattr_t *cond_attr);
int pthread_cond_signal(pthread_cond_t *cond);
int pthread_cond_broadcast(pthread_cond_t *cond);
int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);
int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex,
const struct timespec *abstime);
int pthread_cond_destroy(pthread_cond_t *cond);
الوصف¶
الشرط (اختصار لـ “متغير شرط”) هو أداة تزامن تسمح للخيوط بتعليق التنفيذ والتخلي عن المعالجات حتى يُستوفى بعض المسند على البيانات المشتركة. العمليات الأساسية على الشروط هي: الإشارة إلى الشرط (عندما يصبح المسند صحيحاً)، وانتظار الشرط، مع تعليق تنفيذ الخيط حتى يشير خيط آخر إلى الشرط.
يجب دائمًا ربط متغير الشرط مع كائن المزامنة (mutex)، لتجنب حالة السباق حيث يُحضر خيط للانتظار على متغير شرط ويشير خيط آخر إلى الشرط قبل أن ينتظر الخيط الأول عليه فعليًا.
يهيئ pthread_cond_init متغير الشرط cond، باستخدام سمات الشرط المحددة في cond_attr، أو السمات المبدئية إذا كان cond_attr هو NULL. لا يدعم تنفيذ LinuxThreads سمات للشروط، وبالتالي يُتجاهل معامل cond_attr فعلياً.
يمكن أيضاً تهيئة متغيرات من النوع pthread_cond_t بشكل ثابت، باستخدام الثابت PTHREAD_COND_INITIALIZER.
يعيد pthread_cond_signal تشغيل أحد الخيوط المنتظرة على متغير الشرط cond. إذا لم تكن خيوط تنتظر على cond، لا يحدث شيء. إذا كانت عدة خيوط تنتظر على cond، يُعاد تشغيل واحد بالضبط، لكنه غير محدد أيهما.
يعيد pthread_cond_broadcast تشغيل جميع الخيوط المنتظرة على متغير الشرط cond. لا يحدث شيء إذا لم تكن خيوط تنتظر على cond.
يفتح pthread_cond_wait mutex بشكل ذري (حسب pthread_unlock_mutex) وينتظر الإشارة إلى متغير الشرط cond. يُعلق تنفيذ الخيط ولا يستهلك أي وقت CPU حتى يُشار إلى متغير الشرط. يجب أن يكون mutex مقفلاً بواسطة الخيط المستدعي عند الدخول إلى pthread_cond_wait. قبل العودة إلى الخيط المستدعي، يعيد pthread_cond_wait الحصول على mutex (حسب pthread_lock_mutex).
يتم فتح قفل المِفصل وتعليق الخيط على متغير الشرط بشكل ذري. وبالتالي، إذا حصلت جميع الخيوط دائمًا على المِفصل قبل الإشارة إلى الشرط، فإن هذا يضمن عدم إمكانية الإشارة إلى الشرط (وبالتالي تجاهله) بين الوقت الذي يقفل فيه الخيط المِفصل والوقت الذي ينتظر فيه على متغير الشرط.
تفتح الدالة pthread_cond_timedwait mutex بشكل ذري وتنتظر على cond، كما تفعل pthread_cond_wait، ولكنها أيضًا تحد من مدة الانتظار. إذا لم يتم الإشارة إلى cond خلال المدة الزمنية المحددة بواسطة abstime، يُعاد الحصول على المِفصل mutex وتُرجع pthread_cond_timedwait الخطأ ETIMEDOUT. يُحدد المُعامل abstime وقتًا مطلقًا، بنفس الأصل مثل time(2) وgettimeofday(2): abstime بقيمة 0 يقابل 00:00:00 بتوقيت غرينتش، 1 يناير 1970.
تدمر الدالة pthread_cond_destroy متغير شرط، وتحرر الموارد التي قد يحتفظ بها. يجب ألا تكون أي خيوط في انتظار متغير الشرط عند الدخول إلى pthread_cond_destroy. في تطبيق LinuxThreads، لا توجد موارد مرتبطة بمتغيرات الشرط، وبالتالي لا تفعل pthread_cond_destroy شيئًا فعليًا سوى التحقق من عدم وجود خيوط منتظرة على الشرط.
إلغاء¶
pthread_cond_wait وpthread_cond_timedwait هما نقطتا إلغاء. إذا أُلغي خيط أثناء تعليقه في إحدى هاتين الدالتين، يستأنف الخيط التنفيذ فورًا، ثم يقفل مرة أخرى وسيط mutex الخاص بـ pthread_cond_wait وpthread_cond_timedwait، وأخيرًا ينفذ الإلغاء. وبالتالي، يُضمن لمعالجات التنظيف أن mutex مقفل عند استدعائها.
سلامة الإشارة غير المتزامنة¶
دوال الشرط ليست آمنة للإشارات غير المتزامنة، ولا ينبغي استدعاؤها من معالج إشارة. على وجه الخصوص، قد يؤدي استدعاء pthread_cond_signal أو pthread_cond_broadcast من معالج إشارة إلى تعطيل الخيط المستدعي.
قيمة الإرجاع¶
ترجع جميع دوال متغير الشرط 0 عند النجاح ورمز خطأ غير صفري عند الخطأ.
الأخطاء¶
لا تُرجع الدوال pthread_cond_init وpthread_cond_signal وpthread_cond_broadcast وpthread_cond_wait أي رمز خطأ أبدًا.
تُرجع الدالة pthread_cond_timedwait رموز الخطأ التالية عند حدوث خطأ:
تُرجع الدالة pthread_cond_destroy رمز الخطأ التالي عند حدوث خطأ:
- EBUSY
- بعض الخيوط تنتظر حاليًا على cond.
انظر أيضًا¶
pthread_condattr_init(3)، pthread_mutex_lock(3)، pthread_mutex_unlock(3)، gettimeofday(2)، nanosleep(2).
مثال¶
ضع في اعتبارك متغيرين مشتركين x وy، محميين بواسطة المِفصل mut، ومتغير شرط cond يجب الإشارة إليه كلما أصبح x أكبر من y.
int x,y; pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER; pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
يُجرى الانتظار حتى يصبح x أكبر من y كالتالي:
pthread_mutex_lock(&mut); while (x <= y) { pthread_cond_wait(&cond, &mut); } /* operate on x and y */ pthread_mutex_unlock(&mut);
يجب أن تشير التعديلات على x و y التي قد تجعل x أكبر من y إلى الشرط إذا لزم الأمر:
pthread_mutex_lock(&mut); /* modify x and y */ if (x > y) pthread_cond_broadcast(&cond); pthread_mutex_unlock(&mut);
إذا أمكن إثبات أن خيطًا واحدًا منتظرًا على الأكثر يحتاج إلى الاستيقاظ (على سبيل المثال، إذا كان هناك خيطان فقط يتواصلان عبر x وy)، يمكن استخدام pthread_cond_signal كبديل أكثر كفاءة قليلاً لـ pthread_cond_broadcast. في حالة الشك، استخدم pthread_cond_broadcast.
لانتظار x ليصبح أكبر من y بمهلة 5 ثوانٍ، افعل:
struct timeval now; struct timespec timeout; int retcode; pthread_mutex_lock(&mut); gettimeofday(&now); timeout.tv_sec = now.tv_sec + 5; timeout.tv_nsec = now.tv_usec * 1000; retcode = 0; while (x <= y && retcode != ETIMEDOUT) { retcode = pthread_cond_timedwait(&cond, &mut, &timeout); } if (retcode == ETIMEDOUT) { /* timeout occurred */ } else { /* operate on x and y */ } pthread_mutex_unlock(&mut);
ترجمة¶
تُرجمت هذه الصفحة من الدليل بواسطة زايد السعيدي <zayed.alsaidi@gmail.com>
هذه الترجمة هي وثيقة مجانية؛ راجع رخصة جنو العامة الإصدار 3 أو ما بعده للاطلاع على شروط حقوق النشر. لا توجد أي ضمانات.
إذا وجدت أي أخطاء في ترجمة صفحة الدليل هذه، يرجى إرسال بريد إلكتروني إلى قائمة بريد المترجمين: kde-l10n-ar@kde.org.
| 16 يونيو 2024 | صفحات دليل لينكس 6.9.1 |