Мы задаем нулевой указатель в качестве аргумента нового потока (sigev_value), поэтому функции start нового потока ничего не передается. Мы могли бы передать указатель на дескриптор, вместо того чтобы декларировать его как глобальный, но новому потоку все равно нужно получать атрибуты очереди сообщений и структуру sigev (для перерегистрации). Мы также указываем нулевой указатель в качестве атрибутов нового потока, поэтому используются установки по умолчанию. Новые потоки создаются как неприсоединенные (detached threads). ПРИМЕЧАНИЕ К сожалению, ни одна из использовавшихся для проверки примеров систем (Solaris 2.6 и Digital Unix 4.0B) не поддерживает SIGEV_THREAD. Обе они допускают только два значения sigev_notify: SIGEV_NONE и SIGEV_SIGNAL.Листинг 5.13. Функция mq_notify, запускающая новый программный поток
//pxmsg/mqnotifythread1.с
1 #include "unpipc.h"
2 mqd_t mqd;
3 struct mq_attr attr;
4 struct sigevent sigev;
5 static void notify_thread(union sigval); /* наш поток */
6 int
7 main(int argc, char **argv)
8 {
9 if (argc != 2)
10 err_quit("usage: mqnotifythread1
11 mqd = Mq_open(argv[1], O_RDONLY | O_NONBLOCK);
12 Mq_getattr(mqd, &attr);
13 sigev.sigev_notify = SIGEV_THREAD;
14 sigev.sigev_value.sival_ptr = NULL;
15 sigev.sigev_notify_function = notify_thread;
16 sigev.sigev_notify_attributes = NULL;
17 Mq_notify(mqd, &sigev);
18 for (;;)
19 pause(); /* новый поток делает все */
20 exit(0);
21 }
22 static void
23 notify_thread(union sigval arg)
24 {
25 ssize_t n;
26 void *buff;
27 printf("notify_thread started\n");
28 buff = Malloc(attr.mq_msgsize);
29 Mq_notify(mqd, &sigev); /* перерегистрируемся */
30 while ((n = mq_receive(mqd, buff, attr.mq_msgsize, NULL)) >= 0) {
31 printf("read %ld bytes\n", (long) n);
32 }
33 if (errno != EAGAIN)
34 err_sys("mq_receive error");
35 free(buff);
36 pthread_exit(NULL);
37 }