Вход/Регистрация
UNIX: взаимодействие процессов
вернуться

Стивенс Уильям Ричард

Шрифт:

65 if ((mqinfo = mallос (sizeof (struct mymq_info))) == NULL)

66 goto err;

67 mqinfo->mqi_hdr = mqhdr = (struct mymq_hdr *) mptr;

68 mqinfo->mqi_magic = MQI_MAGIC;

69 mqinfo->mqi_flags = nonblock;

70 /* инициализация заголовка в начале файла */

71 /* создание списка пустых сообщений */

72 mqhdr->mqh_attr.mq_flags = 0;

73 mqhdr->mqh_attr.mq_maxmsg = attr->mq_maxmsg;

74 mqhdr->mqh_attr.mq_msgsize = attr->mq_msgsize;

75 mqhdr->mqh_attr.mq_curmsgs = 0;

76 mqhdr->mqh_nwait = 0;

77 mqhdr->mqh_pid = 0;

78 mqhdr->mqh_head = 0;

79 index = sizeof(struct mymq_hdr);

80 mqhdr->mqh_free = index;

81 for (i = 0; i < attr->mq_maxmsg – 1; i++) {

82 msghdr = (struct mymsg_hdr *) &mptr[index];

83 index += sizeof(struct mymsg_hdr) + msgsize;

84 msghdr->msg_next = index;

85 }

86 msghdr = (struct mymsg_hdr *) &mptr[index];

87 msghdr->msg_next = 0; /* конец списка пустых сообщений */

88 /* инициализация взаимного исключения и условной переменной */

89 if ((i = pthread_mutexattr_init(&mattr)) != 0)

90 goto pthreaderr;

91 pthread_mutexattr_setpshared(&mattr, PTHREAD_PROCESS_SHARED);

92 i = pthread_mutex_init(&mqhdr->mqh_lock, &mattr);

93 pthread_mutexattr_destroy(&mattr); /* обязательно нужно удалить */

94 if (i != 0)

95 goto pthreaderr:

96 if ((i = pthread_condattr_init(&cattr)) != 0)

97 goto pthreaderr;

98 pthread_condattr_setpshared(&cattr, PTHREAD_PROCESS_SHARED);

99 i = pthread_cond_init(&mqhdr->mqh_wait, &cattr);

100 pthread_condattr_destroy(&cattr); /* обязательно нужно удалить */

101 if (i != 0)

102 goto pthreaderr;

103 /* инициализация завершена, снимаем бит user-execute */

104 if (fchmod(fd, mode) == –1)

105 goto err;

106 close(fd);

107 return((mymqd_t) mqinfo);

108 }

Установка размера файла

51-58 Вычисляется размер сообщения, который затем округляется до кратного размеру длинного целого. Также в файле отводится место для структуры mq_hdr в начале файла и msghdr в начале каждого сообщения (рис. 5.2). Размер вновь созданного файла устанавливается функцией lseek и записью одного байта со значением 0. Проще было бы вызвать ftruncate (раздел 13.3), но у нас нет гарантий, что это сработало бы для увеличения размера файла.

Отображение файла в память

59-63 Файл отображается в память функцией mmap.

Выделение памяти под структуру mq_info

64-66 При каждом вызове mq_open создается отдельный экземпляр mq_infо. Эта структура после создания инициализируется.

Инициализация структуры mq_hdr

67-87 Инициализируется структура mq_hdr. Заголовок связного списка сообщений (mqh_head) инициализируется нулем, а все сообщения в очереди добавляются к списку свободных (mqh_frее).

Инициализация взаимного исключения и условной переменной

88-102 Поскольку очереди сообщений Posix могут использоваться совместно произвольным количеством процессов, которые знают имя очереди и имеют соответствующие разрешения, нам нужно инициализировать взаимное исключение и условную переменную с атрибутом PTHREAD_PROCESS_SHARED. Для этого мы сначала инициализируем атрибуты вызовом pthread_mutexattr_init, а затем устанавливаем значение атрибута совместного использования процессами, вызвав pthread_mutexattr_setpshared. После этого взаимное исключение инициализируется вызовом pthread_mutex_init. Аналогичные действия выполняются для условной переменной. Мы должны аккуратно удалить взаимное исключение и условную переменную даже при возникновении ошибки, поскольку вызовы pthread_ mutexattr_init и pthread_condattr_init выделяют под них память (упражнение 7.3).

  • Читать дальше
  • 1
  • ...
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: