sem_wait(3)

الاسم
sem_wait, sem_timedwait, sem_trywait - قفل كمية

المكتبة
مكتبة مسالك POSIX (libpthread، -lpthread)

موجز
#include <semaphore.h>

int sem_wait(sem_t *sem);
int sem_trywait(sem_t *sem);
int sem_timedwait(sem_t *restrict sem,
                  const struct timespec *restrict abs_timeout);

    متطلبات ماكروات اختبار الميزات لـ glibc (انظر feature_test_macros(7)):

sem_timedwait():
    _POSIX_C_SOURCE >= 200112L

الوصف
sem_wait() تُنقص (تقفل) الكمية المشار إليها بواسطة sem. إذا كانت قيمة الكمية أكبر من الصفر، فإن النقص يجري، وتعود الدالة فورًا. إذا كانت الكمية حاليًا قيمتها صفر، فإن الاستدعاء يُحجب حتى يصبح من الممكن إجراء النقص (أي ترتفع قيمة الكمية فوق الصفر)، أو يقاطع معالج إشارة الاستدعاء.

sem_trywait() هي نفس sem_wait()، باستثناء أنه إذا تعذر إجراء النقص فورًا، فإن الاستدعاء يُرجع خطأ (errno مضبوط على EAGAIN) بدلاً من الحجب.

sem_timedwait() هي نفس sem_wait()، باستثناء أن abs_timeout يُحدد حدًا لمقدار الوقت الذي يجب أن يُحجب فيه الاستدعاء إذا تعذر إجراء النقص فورًا. وسيطة abs_timeout تُشير إلى بنية timespec(3) التي تُحدد مهلة مطلقة بالثواني والنانوثواني منذ العصر، 1970-01-01 00:00:00 +0000 (UTC).

إذا كانت المهلة قد انتهت بالفعل بحلول وقت الاستدعاء، ولم يمكن قفل الكمية فورًا، فإن sem_timedwait() تفشل مع خطأ مهلة (errno مضبوط على ETIMEDOUT).

إذا أمكن إجراء العملية فورًا، فإن sem_timedwait() لا تفشل أبدًا مع خطأ مهلة، بغض النظر عن قيمة abs_timeout. علاوة على ذلك، لا يُفحص صحة abs_timeout في هذه الحالة.

قيمة الإرجاع
كل هذه الدوال تُرجع 0 عند النجاح؛ عند الخطأ، تُترك قيمة الكمية دون تغيير، وتُعاد -1، ويُضبط errno للإشارة إلى الخطأ.

الأخطاء

EAGAIN
    (sem_trywait()) تعذر إجراء العملية دون حجب (أي الكمية حاليًا قيمتها صفر).

EINTR
    قُطع الاستدعاء بواسطة معالج إشارات؛ انظر signal(7).

EINVAL
    sem ليس إشارة (semaphore) صالحة.

EINVAL
    (sem_timedwait()) قيمة abs_timeout.tv_nsecs أقل من 0، أو أكبر من أو تساوي 1000 مليون.

ETIMEDOUT
    (sem_timedwait()) انتهت مهلة الاستدعاء قبل أن يمكن قفل الكمية.

السمات
للاطلاع على شرح للمصطلحات المستخدمة في هذا القسم، انظر attributes(7).
الواجهة | السمة | القيمة
sem_wait(), sem_trywait(), sem_timedwait() | سلامة الخيوط | MT-Safe

المعايير
POSIX.1-2008.

التاريخ
POSIX.1-2001.

أمثلة
البرنامج (التافه نوعًا ما) الموضح أدناه يعمل على كمية غير مسماة. يتوقع البرنامج وسيطتين لسطر الأوامر. تحدد الوسيطة الأولى قيمة ثوانٍ تُستخدم لضبط مؤقت إنذار لتوليد إشارة SIGALRM. يُنفذ هذا المعالج sem_post(3) لزيادة الكمية التي يُنتظر عليها في main() باستخدام sem_timedwait(). تحدد وسيطة سطر الأوامر الثانية طول المهلة، بالثواني، لـ sem_timedwait(). يُظهر التالي ما يحدث في تشغيلين مختلفين للبرنامج:

    $ ./a.out 2 3
    About to call sem_timedwait()
    sem_post() from handler
    sem_timedwait() succeeded
    $ ./a.out 2 1
    About to call sem_timedwait()
    sem_timedwait() timed out

  مصدر البرنامج
    #include <err.h>
    #include <errno.h>
    #include <semaphore.h>
    #include <signal.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    #include <unistd.h>

    #include <assert.h>

    sem_t sem;

    static void
    handler(int sig)
    {
        write(STDOUT_FILENO, "sem_post() from handler\n", 24);
        if (sem_post(&sem) == -1) {
            write(STDERR_FILENO, "sem_post() failed\n", 18);
            _exit(EXIT_FAILURE);
        }
    }

    int
    main(int argc, char *argv[])
    {
        struct sigaction sa;
        struct timespec ts;
        int s;

        if (argc != 3) {
            fprintf(stderr, "Usage: %s <alarm-secs> <wait-secs>\n",
                    argv[0]);
            exit(EXIT_FAILURE);
        }

        if (sem_init(&sem, 0, 0) == -1)
            err(EXIT_FAILURE, "sem_init");

        /* Establish SIGALRM handler; set alarm timer using argv[1].  */

        sa.sa_handler = handler;
        sigemptyset(&sa.sa_mask);
        sa.sa_flags = 0;
        if (sigaction(SIGALRM, &sa, NULL) == -1)
            err(EXIT_FAILURE, "sigaction");

        alarm(atoi(argv[1]));

        /* Calculate relative interval as current time plus
           number of seconds given argv[2].  */

        if (clock_gettime(CLOCK_REALTIME, &ts) == -1)
            err(EXIT_FAILURE, "clock_gettime");

        ts.tv_sec += atoi(argv[2]);

        printf("%s() about to call sem_timedwait()\n", __func__);
        while ((s = sem_timedwait(&sem, &ts)) == -1 && errno == EINTR)
            continue;       /* Restart if interrupted by handler.  */

        /* Check what happened.  */

        if (s == -1) {
            if (errno == ETIMEDOUT)
                printf("sem_timedwait() timed out\n");
            else
                perror("sem_timedwait");
        } else
            printf("sem_timedwait() succeeded\n");

        exit((s == 0) ? EXIT_SUCCESS : EXIT_FAILURE);
    }

انظر أيضًا
clock_gettime(2), sem_getvalue(3), sem_post(3), timespec(3), sem_overview(7), time(7)

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

هذه الترجمة هي وثيقة مجانية؛ راجع رخصة جنو العامة الإصدار 3 (https://www.gnu.org/licenses/gpl-3.0.html) أو ما بعده للاطلاع على شروط حقوق النشر. لا توجد أي ضمانات.

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