mq_notify(3)

NUME
mq_notify - înregistrare pentru notificare atunci când un mesaj este disponibil

BIBLIOTECA
Biblioteca de timp real (librt, -lrt)

SINOPSIS
#include <mqueue.h>
#include <signal.h>           /* Definiția constantelor SIGEV_* */

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

DESCRIERE
mq_notify() permite procesului apelant să se înregistreze sau să-și anuleze înregistarea pentru a primi o notificare asincronă atunci când un mesaj nou sosește în coada de mesaje goală la care se face referire în descriptorul cozii de mesaje mqdes.

Argumentul sevp este un indicator către o structură sigevent. Pentru definiția și detaliile generale ale acestei structuri, a se vedea sigevent(3type).

Dacă sevp este un indicator nenul, atunci mq_notify() înregistrează procesul apelant pentru a primi notificarea mesajului. Câmpul sigev_notify din structura sigevent către care indică sevp specifică modul în care trebuie efectuată notificarea. Acest câmp are una dintre următoarele valori:

SIGEV_NONE
    O notificare „nulă”: procesul apelant este înregistrat ca țintă pentru notificare, dar atunci când sosește un mesaj, nu este trimisă nicio notificare.

SIGEV_SIGNAL
    Notifică procesul prin trimiterea semnalului specificat în sigev_signo. A se vedea sigevent(3type) pentru detalii generale. Câmpul si_code din structura siginfo_t va fi stabilit la SI_MESGQ. În plus, si_pid va fi definit la PID-ul procesului care a trimis mesajul, iar si_uid va fi definit la ID-ul utilizatorului real al procesului de trimitere.

SIGEV_THREAD
    La livrarea mesajului, se invocă sigev_notify_function ca și cum ar fi funcția de pornire a unui nou fir de execuție. Consultați sigevent(3type) pentru detalii.

Un singur proces poate fi înregistrat pentru a primi notificări de la o coadă de mesaje.

Dacă sevp este NULL, iar procesul apelant este înregistrat în prezent pentru a primi notificări pentru această coadă de mesaje, atunci înregistrarea este eliminată; un alt proces se poate înregistra apoi pentru a primi o notificare de mesaj pentru această coadă.

Notificarea mesajelor are loc numai atunci când sosește un mesaj nou și coada a fost golită anterior. Dacă coada nu era goală în momentul apelării mq_notify(), atunci o notificare va avea loc numai după ce coada este golită și sosește un mesaj nou.

Dacă un alt proces sau fir de execuție așteaptă să citească un mesaj dintr-o coadă goală folosind mq_receive(3), atunci orice înregistrare de notificare a mesajului este ignorată: mesajul este livrat procesului sau firului de execuție care apelează mq_receive(3), iar înregistrarea de notificare a mesajului rămâne în vigoare.

Notificarea are loc o singură dată: după livrarea unei notificări, înregistrarea notificării este eliminată, iar un alt proces se poate înregistra pentru notificarea mesajului. Dacă procesul notificat dorește să primească următoarea notificare, acesta poate utiliza mq_notify() pentru a solicita o nouă notificare. Acest lucru trebuie făcut înainte de golirea tuturor mesajelor necitite din coadă; (pasarea cozii în modul de ne-blocare este utilă pentru golirea cozii de mesaje fără blocare odată ce aceasta este goală).

VALOAREA RETURNATĂ
În caz de succes, mq_notify() returnează 0; în caz de eroare, se returnează -1, cu errno configurată pentru a indica eroarea.

ERORI-IEȘIRE

EBADF
    Descriptorul de coadă de mesaje specificat în mqdes nu este valid.

EBUSY
    Un alt proces s-a înregistrat deja pentru a primi notificare pentru această coadă de mesaje.

EINVAL
    sevp->sigev_notify nu este una dintre valorile permise; sau sevp->sigev_notify este SIGEV_SIGNAL și sevp->sigev_signo nu este un număr de semnal valid.

ENOMEM
    Memorie insuficientă.

POSIX.1-2008 spune că o implementare poate genera o eroare EINVAL dacă sevp este NULL, iar apelantul nu este înregistrat în prezent pentru a primi notificări pentru coada mqdes.

ATRIBUTE
Pentru o explicație a termenilor folosiți în această secțiune, a se vedea attributes(7).
Interfață | Atribut | Valoare
mq_notify() | Siguranța firelor | MT-Safe

VERSIUNI

  Diferențe între biblioteca C și nucleu
În implementarea glibc, funcția de bibliotecă mq_notify() este implementată peste apelul de sistem cu același nume. Atunci când sevp este NULL sau specifică un alt mecanism de notificare decât SIGEV_THREAD, funcția de bibliotecă invocă direct apelul sistemului. Pentru SIGEV_THREAD, o mare parte din implementare se află în bibliotecă, și nu în nucleu; (acest lucru este necesar, deoarece firul implicat în gestionarea notificării este unul care trebuie gestionat de implementarea firelor POSIX din biblioteca C). Implementarea implică utilizarea unui soclu netlink(7) brut și creează un nou fir pentru fiecare notificare care este transmisă procesului.

STANDARDE
POSIX.1-2008.

ISTORIC
POSIX.1-2001.

EXEMPLE
Următorul program înregistrează o cerere de notificare pentru coada de mesaje numită în argumentul său din linia de comandă. Notificarea este efectuată prin crearea unui fir de execuție. Firul execută o funcție care citește un mesaj din coadă și apoi termină procesul.

  Sursa programului
    #include <err.h>
    #include <mqueue.h>
    #include <pthread.h>
    #include <signal.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>

    #define handle_error(msg) \
        do { perror(msg); exit(EXIT_FAILURE); } while (0)

    static void                     /* Firul pornește funcția */
    tfunc(union sigval sv)
    {
        struct mq_attr attr;
        ssize_t nr;
        void *buf;
        mqd_t mqdes = *((mqd_t *) sv.sival_ptr);

        /* Determină dimensiunea maximă a mesajului; alocă memorie tampon pentru primirea mesajului */

        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("Citiți %zd octeți din MQ\n", nr);
        free(buf);
        exit(EXIT_SUCCESS);         /* Terminarea procesului */
    }

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

        if (argc != 2) {
            fprintf(stderr, "Utilizare: %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;   /* Argument pentru funcția firului */
        if (mq_notify(mqdes, &sev) == -1)
            err(EXIT_FAILURE, "mq_notify");

        pause();    /* Procesul va fi finalizat de funcția firului */
    }

CONSULTAȚI ȘI
mq_close(3), mq_getattr(3), mq_open(3), mq_receive(3), mq_send(3), mq_unlink(3), mq_overview(7), sigevent(3type)

TRADUCERE
Traducerea în limba română a acestui manual a fost făcută de Remus-Gabriel Chelu <remusgabriel.chelu@disroot.org>

Această traducere este documentație gratuită; citiți Licența publică generală GNU Versiunea 3 (https://www.gnu.org/licenses/gpl-3.0.html) sau o versiune ulterioară cu privire la condiții privind drepturile de autor. NU se asumă NICIO RESPONSABILITATE.

Dacă găsiți erori în traducerea acestui manual, vă rugăm să trimiteți un e-mail la translation-team-ro@lists.sourceforge.net.