mq_notify(3)

الاسم
mq_notify - سجّل للاستعلام عندما تكون رسالة متاحة

المكتبة
مكتبة الوقت الحقيقي (librt، -lrt)

موجز
#include <mqueue.h>
#include <signal.h>           /* Definition of SIGEV_* constants */

int mq_notify(mqd_t mqdes, const struct sigevent *sevp);

الوصف
تسمح الدالة mq_notify() للعملية المستدعية بتسجيل أو إلغاء تسجيل استلام إعلام غير متزامن عند وصول رسالة جديدة إلى طابور الرسائل الفارغ المشار إليه بواصف طابور الرسائل mqdes.

المعامل sevp هو مؤشر إلى بنية sigevent. للتعريف والتفاصيل العامة لهذه البنية، انظر sigevent(3type).

إذا كان sevp مؤشرًا غير فارغ، فإن mq_notify() تسجل العملية المستدعية لتلقي إعلام الرسالة. يحدد حقل sigev_notify من بنية sigevent التي يشير إليها sevp كيفية تنفيذ الإعلام. لهذا الحقل إحدى القيم التالية:

SIGEV_NONE
    إعلام "فارغ": تُسجل العملية المستدعية كهدف للإعلام، ولكن عند وصول رسالة، لا يُرسل أي إعلام.

SIGEV_SIGNAL
    أعلم العملية بإرسال الإشارة المحددة في sigev_signo. انظر sigevent(3type) للتفاصيل العامة. سيُضبط حقل si_code من بنية siginfo_t إلى SI_MESGQ. بالإضافة إلى ذلك، سيُضبط si_pid إلى PID العملية التي أرسلت الرسالة، وسيُضبط si_uid إلى معرف المستخدم الحقيقي للعملية المرسلة.

SIGEV_THREAD
    عند تسليم الرسالة، استدعِ sigev_notify_function كما لو كانت دالة بدء خيط جديد. انظر sigevent(3type) للتفاصيل.

يمكن تسجيل عملية واحدة فقط لتلقي الإعلام من طابور رسائل.

إذا كان sevp فارغًا، وكانت العملية المستدعية مسجلة حاليًا لتلقي إعلامات لهذا الطابور، فسيُزال التسجيل؛ ويمكن لعملية أخرى التسجيل لتلقي إعلام رسالة لهذا الطابور.

يحدث إعلام الرسالة فقط عند وصول رسالة جديدة وكان الطابور فارغًا سابقًا. إذا لم يكن الطابور فارغًا في وقت استدعاء mq_notify() ، فسيحدث الإعلام فقط بعد إفراغ الطابور ووصول رسالة جديدة.

إذا كانت عملية أو خيط آخر ينتظر قراءة رسالة من طابور فارغ باستخدام mq_receive(3)، فسيُتجاهل أي تسجيل إعلام رسالة: تُسلم الرسالة إلى العملية أو الخيط المستدعي mq_receive(3)، ويبقى تسجيل إعلام الرسالة ساري المفعول.

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

قيمة الإرجاع
عند النجاح، تُرجع mq_notify() 0؛ عند الخطأ، تُرجع -1، مع ضبط errno للإشارة إلى الخطأ.

الأخطاء

EBADF
    واصف قائمة رسائل المحدد في mqdes غير صالح.

EBUSY
    سُجلت عملية أخرى بالفعل لتلقي الإعلام لهذا الطابور.

EINVAL
    sevp->sigev_notify ليس إحدى القيم المسموح بها؛ أو sevp->sigev_notify هو SIGEV_SIGNAL و sevp->sigev_signo ليس رقم إشارة صالحًا.

ENOMEM
    ذاكرة غير كافية.

ينص POSIX.1-2008 على أن التطبيق قد يُنشئ خطأ EINVAL إذا كان sevp فارغًا، ولم يكن المستدعي مسجلاً حاليًا لتلقي إعلامات للطابور mqdes.

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

الإصدارات

  الاختلافات بين مكتبة C والنواة
في تطبيق glibc، تُنفذ دالة المكتبة mq_notify() فوق استدعاء النظام الذي يحمل نفس الاسم. عندما يكون sevp فارغًا، أو يحدد آلية إعلام غير SIGEV_THREAD، تستدعي دالة المكتبة استدعاء النظام مباشرة. بالنسبة لـ SIGEV_THREAD، يقع جزء كبير من التطبيق داخل المكتبة، وليس النواة. (هذا ضروري، لأن الخيط المشارك في معالجة الإعلام هو خيط يجب إدارته بواسطة تطبيق خيوط POSIX لمكتبة C.) يتضمن التطبيق استخدام مقبس netlink(7) خام وإنشاء خيط جديد لكل إعلام يُسلم إلى العملية.

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

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

أمثلة
يسجل البرنامج التالي طلب إشعار لطابور الرسائل المُسمى في وسيط سطر الأوامر. يُنفَّذ الإشعار بإنشاء خيط. يُنفِّذ الخيط دالة تقرأ رسالة واحدة من الطابور ثم تُنهي العملية.

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

    static void                     /* Thread start function */
    tfunc(union sigval sv)
    {
        struct mq_attr attr;
        ssize_t nr;
        void *buf;
        mqd_t mqdes = *((mqd_t *) sv.sival_ptr);

        /* Determine max. msg size; allocate buffer to receive msg */

        if (mq_getattr(mqdes, &attr) == -1)
            err(EXIT_FAILURE, "mq_getattr");
        buf = malloc(attr.mq_msgsize);
        if (buf == NULL)
            err(EXIT_FAILURE, "malloc");

        nr = mq_receive(mqdes, buf, attr.mq_msgsize, NULL);
        if (nr == -1)
            err(EXIT_FAILURE, "mq_receive");

        printf("Read %zd bytes from MQ\n", nr);
        free(buf);
        exit(EXIT_SUCCESS);         /* Terminate the process */
    }

    int
    main(int argc, char *argv[])
    {
        mqd_t mqdes;
        struct sigevent sev;

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

        mqdes = mq_open(argv[1], O_RDONLY);
        if (mqdes == (mqd_t) -1)
            err(EXIT_FAILURE, "mq_open");

        sev.sigev_notify = SIGEV_THREAD;
        sev.sigev_notify_function = tfunc;
        sev.sigev_notify_attributes = NULL;
        sev.sigev_value.sival_ptr = &mqdes;   /* Arg. to thread func.  */
        if (mq_notify(mqdes, &sev) == -1)
            err(EXIT_FAILURE, "mq_notify");

        pause();    /* Process will be terminated by thread function */
    }

انظر أيضًا
mq_close(3), mq_getattr(3), mq_open(3), mq_receive(3), mq_send(3), mq_unlink(3), mq_overview(7), sigevent(3type)

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

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

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