Чтение онлайн

на главную - закладки

Жанры

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

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

Шрифт:

59 pmsghdr = (struct mymsg_hdr *) &(mqhdr->mqh_head);

60 while (index != 0) {

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

62 if (prio > msghdr->msg_prio) {

63 nmsghdr->msg_next = index;

64 pmsghdr->msg_next = freeindex;

65 break;

66 }

67 index = msghdr->msg_next;

68 pmsghdr = msghdr;

69 }

70 if (index == 0) {

71 /* очередь была пуста или новое письмо добавлено к концу списка */

72 pmsghdr->msg_next = freeindex;

73 nmsghdr->msg_next = 0;

74 }

75 /* запускаем любой из процессов, заблокированных в mq_receive */

76 if (attr->mq_curmsgs == 0)

77 pthread_cond_signal(&mqhdr->mqh_wait);

78 attr->mq_curmsgs++;

79 pthread_mutex_unlock(&mqhdr->mqh_lock);

80 return(0);

81 err:

82 pthread_mutex_unlock(&mqhdr->mqh lock);

83 return(-1);

84 }

Получение индекса свободного блока

50-52 Поскольку количество свободных сообщений при создании очереди равно mq_maxmsg, ситуация, в которой mq_curmsgs будет меньше mq_maxmsg для пустого списка свободных сообщений, возникнуть не может.

Копирование сообщения

53-56 Указатель nmsghdr хранит адрес области памяти, в которую помещается сообщение. Приоритет и длина сообщения сохраняются в структуре msg_hdr, а затем в память копируется содержимое сообщения, переданного вызвавшим процессом.

Помещение нового сообщения в соответствующее место связного списка

57-74 Порядок сообщений в нашем списке зависит от их приоритета: они расположены в порядке его убывания. При добавлении нового сообщения мы проверяем, существуют ли сообщения с тем же приоритетом; в этом случае сообщение добавляется после последнего из них. Используя такой метод упорядочения, мы гарантируем, что mq_receive всегда будет возвращать старейшее сообщение с наивысшим приоритетом. По мере продвижения по списку мы сохраняем в pmsghdr адрес предыдущего сообщения, поскольку именно это сообщение будет хранить индекс нового сообщения в поле msg_next.

ПРИМЕЧАНИЕ

Наша схема может оказаться медленной в случае наличия в очереди большого количества сообщений, поскольку каждый раз при добавлении нового придется просматривать их значительную часть. Можно хранить отдельно индексы последних сообщений со всеми имеющимися значениями приоритета. 

Пробуждение любого процесса, заблокированного в вызове mq_receive

75-77 Если очередь была пуста в момент помещения в нее нового сообщения, мы вызываем pthread_cond_signal, чтобы разблокировать любой из процессов, ожидающих сообщения.

78 Увеличиваем на единицу количество сообщений в очереди mq_curmsgs.

Функция mq_receive

В листинге 5.27 приведен текст первой половины функции mq_receive, которая получает необходимые указатели, блокирует взаимное исключение и проверяет объем буфера вызвавшего процесса, который должен быть достаточным для помещения туда сообщения максимально возможной длины.

Проверка полноты очереди

30-40 Если очередь пуста и установлен флаг O_NONBLOCK, возвращается ошибка с кодом EAGAIN. В противном случае увеличивается значение счетчика mqh_nwait, который проверяется функцией mq_send (листинг 5.25) в случае, если очередь пуста и есть процессы, ожидающие уведомления. Затем мы ожидаем сигнала по условной переменной, который будет передан функцией mq_send (листинг 5.26).

ПРИМЕЧАНИЕ

Наша реализация mq_receive, как и реализация mq_send, упрощает ситуацию с ошибкой EINTR, возвращаемой при прерывании ожидания сигналом, перехватываемым вызвавшим процессом.

В листинге 5.28 приведен текст второй половины функции mq_receive. Мы уже знаем, что в очереди есть сообщение, которое можно будет возвратить вызвавшему процессу.

Листинг 5.27.Функция mq_receive: первая половина

//my_pxmsg_mmap/mq_receive.с

1 #include "unpipc.h"

2 #include "mqueue.h"

3 ssize_t

4 mymq_receive(mymqd_t mqd, char *ptr, size_t maxlen, unsigned int *priop)

5 {

6 int n;

7 long index;

8 int8_t *mptr;

9 ssize_t len;

10 struct mymq_hdr *mqhdr;

11 struct mymq_attr *attr;

12 struct mymsg_hdr *msghdr;

13 struct mymq_info *mqinfo;

14 mqinfo = mqd;

15 if (mqinfo->mqi_magic != MQI_MAGIC) {

16 errno = EBADF;

17 return(-1);

18 }

19 mqhdr = mqinfo->mqi_hdr; /* указатель struct */

20 mptr = (int8_t *) mqhdr; /* указатель на байт */

21 attr = &mqhdr->mqh_attr;

22 if ((n = pthread_mutex_lock(&mqhdr->mqh_lock)) != 0) {

23 errno = n;

24 return(-1);

25 }

26 if (maxlen < attr->mq_msgsize) {

27 errno = EMSGSIZE;

28 goto err;

29 }

30 if (attr->mq_curmsgs = 0) { /* очередь пуста */

31 if (mqinfo->mqi_flags & O_NONBLOCK) {

32 errno = EAGAIN;

33 goto err;

34 }

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

Двойник короля 21

Скабер Артемий
21. Двойник Короля
Фантастика:
аниме
фэнтези
попаданцы
5.00
рейтинг книги
Двойник короля 21

Газлайтер. Том 9

Володин Григорий
9. История Телепата
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Газлайтер. Том 9

Я не бог. Книга XXXIV

Дрейк Сириус
34. Дорогой барон!
Фантастика:
юмористическое фэнтези
аниме
попаданцы
5.00
рейтинг книги
Я не бог. Книга XXXIV

Я Гордый часть 2

Машуков Тимур
2. Стальные яйца
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Я Гордый часть 2

Евангелие от зверя

Головачев Василий Васильевич
Шедевры отечественной фантастики
Фантастика:
фэнтези
альтернативная история
4.57
рейтинг книги
Евангелие от зверя

Лекарь

Назимов Константин Геннадьевич
2. Травник
Фантастика:
фэнтези
5.25
рейтинг книги
Лекарь

Черный Маг Императора 19

Герда Александр
19. Черный маг императора
Фантастика:
аниме
фэнтези
попаданцы
5.00
рейтинг книги
Черный Маг Императора 19

Бастард Императора. Том 11

Орлов Андрей Юрьевич
11. Бастард Императора
Фантастика:
городское фэнтези
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Бастард Императора. Том 11

Мл. сержант. Назад в СССР. Книга 3

Гаусс Максим
3. Второй шанс
Фантастика:
альтернативная история
6.40
рейтинг книги
Мл. сержант. Назад в СССР. Книга 3

Последний Паладин. Том 3

Саваровский Роман
3. Путь Паладина
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Последний Паладин. Том 3

Тринадцатый VI

NikL
6. Видящий смерть
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Тринадцатый VI

Воплощение Похоти

Некрасов Игорь
1. Воплощение Похоти
Фантастика:
юмористическое фэнтези
попаданцы
рпг
аниме
5.00
рейтинг книги
Воплощение Похоти

Черный маг императора 2

Герда Александр
2. Черный маг императора
Фантастика:
юмористическая фантастика
попаданцы
аниме
6.00
рейтинг книги
Черный маг императора 2

Запечатанный во тьме. Том 2

NikL
2. Хроники Арнея
Фантастика:
уся
эпическая фантастика
фэнтези
5.00
рейтинг книги
Запечатанный во тьме. Том 2