c/mqueues.c (3495 bytes)
1 #include <mqueue.h> 2 #include <stdlib.h> 3 #include <stdio.h> 4 #include <errno.h> 5 6 #define MSG_SIZE 4096 7 8 // This handler will be called when the queue 9 // becomes non-empty. 10 11 void handler (int sig_num) { 12 printf ("Received sig %d.\n", sig_num); 13 } 14 15 void main () { 16 17 struct mq_attr attr, old_attr; // To store queue attributes 18 struct sigevent sigevent; // For notification 19 mqd_t mqdes, mqdes2; // Message queue descriptors 20 char buf[MSG_SIZE]; // A good-sized buffer 21 unsigned int prio; // Priority 22 23 // First we need to set up the attribute structure 24 attr.mq_maxmsg = 300; 25 attr.mq_msgsize = MSG_SIZE; 26 attr.mq_flags = 0; 27 28 // Open a queue with the attribute structure 29 mqdes = mq_open ("sideshow-bob", O_RDWR | O_CREAT, 30 0664, &attr); 31 32 // Now open a queue with the default attribute structure 33 mqdes2 = mq_open ("troy-mcclure", O_RDWR | O_CREAT, 34 0664, 0); 35 36 // This will now be a temporary queue...as soon as it's closed, 37 // it will be removed 38 mq_unlink ("troy-mcclure"); 39 40 // Get the attributes for Sideshow Bob 41 mq_getattr (mqdes, &attr); 42 printf ("%d messages are currently on the queue.\n", 43 attr.mq_curmsgs); 44 45 if (attr.mq_curmsgs != 0) { 46 47 // There are some messages on this queue....eat em 48 49 // First set the queue to not block any calls 50 attr.mq_flags = MQ_NONBLOCK; 51 mq_setattr (mqdes, &attr, &old_attr); 52 53 // Now eat all of the messages 54 while (mq_receive (mqdes, &buf[0], MSG_SIZE, &prio) != -1) 55 printf ("Received a message with priority %d.\n", prio); 56 57 // The call failed. Make sure errno is EAGAIN 58 if (errno != EAGAIN) { 59 perror ("mq_receive()"); 60 _exit (EXIT_FAILURE); 61 } 62 63 // Now restore the attributes 64 mq_setattr (mqdes, &old_attr, 0); 65 } 66 67 // We want to be notified when something is there 68 signal (SIGUSR1, handler); 69 sigevent.sigev_signo = SIGUSR1; 70 71 if (mq_notify (mqdes, &sigevent) == -1) { 72 if (errno == EBUSY) 73 printf ( 74 "Another process has registered for notification.\n"); 75 _exit (EXIT_FAILURE); 76 } 77 78 for (prio = 0; prio <= MQ_PRIO_MAX; prio += 8) { 79 printf ("Writing a message with priority %d.\n", prio); 80 if (mq_send (mqdes, "I8-)", 4, prio) == -1) 81 perror ("mq_send()"); 82 } 83 84 // Close all open message queue descriptors 85 mq_close (mqdes); 86 mq_close (mqdes2); 87 88 } 89 The first time the example program is run, the output should be as follows: 90 91 $ mq_test 92 0 messages are currently on the queue. 93 Writing a message with priority 0. 94 Received sig 16. 95 Writing a message with priority 8. 96 Writing a message with priority 16. 97 Writing a message with priority 24. 98 Writing a message with priority 32. 99 After the program wrote to the empty queue, it was signalled that the queue had made the transition from empty to nonempty. The second time the example program is run, the following should be produced: 100 101 $ mq_test 102 5 messages are currently on the queue. 103 Received a message with priority 32. 104 Received a message with priority 24. 105 Received a message with priority 16. 106 Received a message with priority 8. 107 Received a message with priority 0. 108 Writing a message with priority 0. 109 Received sig 16. 110 Writing a message with priority 8. 111 Writing a message with priority 16. 112 Writing a message with priority 24. 113 Writing a message with priority 32. 114 Note that the first message received was the message with the highest priority, with all of the other priorities following in suit. 115