Книга: UNIX: взаимодействие процессов

Пример: запуск нового потока

Пример: запуск нового потока

Альтернативой снятию блокировки сигналом является присваивание sigev_notify значения SIGEV_THREAD, что приводит к созданию нового потока. Функция, указанная в sigev_notify_function, вызывается с параметром sigev_value. Атрибуты нового канала указываются переменной sigev_notify_attributes, которая может быть и нулевым указателем, если нас устраивают устанавливаемые по умолчанию атрибуты. Текст программы приведен в листинге 5.13.

Листинг 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 <name>");
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 startedn");
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 bytesn", (long) n);
32  }
33  if (errno != EAGAIN)
34   err_sys("mq_receive error");
35  free(buff);
36  pthread_exit(NULL);
37 }

Мы задаем нулевой указатель в качестве аргумента нового потока (sigev_value), поэтому функции start нового потока ничего не передается. Мы могли бы передать указатель на дескриптор, вместо того чтобы декларировать его как глобальный, но новому потоку все равно нужно получать атрибуты очереди сообщений и структуру sigev (для перерегистрации). Мы также указываем нулевой указатель в качестве атрибутов нового потока, поэтому используются установки по умолчанию. Новые потоки создаются как неприсоединенные (detached threads).

ПРИМЕЧАНИЕ

К сожалению, ни одна из использовавшихся для проверки примеров систем (Solaris 2.6 и Digital Unix 4.0B) не поддерживает SIGEV_THREAD. Обе они допускают только два значения sigev_notify: SIGEV_NONE и SIGEV_SIGNAL.

Оглавление книги


Генерация: 0.058. Запросов К БД/Cache: 0 / 0
поделиться
Вверх Вниз