Главная страница Взаимодействие нетривиальных процессов Разблокирование процесса, заблокированного в вызове mq send 52-54 Если очередь была полной в момент считывания сообщения, мы вызываем ptliread cond signal для отправки сообщения любому из процессов, заблокированных в вызове mq send. 5.9. Резюме Очереди сообщений Posix просты в использовании: новая очередь создается (или существующая открывается) функцией mqopen; закрываются очереди вызовом mq cl ose, а удаляются mqunl i nk. Поместить сообщение в очередь можно функцией mq send, а считать его оттуда можно с помощью mq recei ve. Атрибуты очереди можно считать и установить с помощью функций mq getattr и mq setattr, а функция mq noti fy позволяет зарегистрировать процесс на уведомление о помещении нового сообщения в пустую очередь. Каждое сообщение в очереди обладает приоритетом (небольшое целое число), и функция mqrecei ve всегда возвращает старейшее сообщение с наивысшим приоритетом. Изучая mq noti fy, мы познакомились с сигналами реального времени стандарта Posix, которые обладают номерами от SIGMIN до SIGMAX. При установке обработчика для этих сигналов с флагом SA SIGINFO они будут помещаться в очередь, доставляться в порядке очереди и сопровождаться двумя дополнительными аргументами (при вызове обработчика). Наконец, мы реализовали большую часть возможностей очереди сообщений Posix в приблизительно 500 строках кода на языке С, используя отображаемые в память файлы, взаимные исключения и условные переменные Posix. Эта реализация иллюстрирует обработку ситуации гонок при создании новой очереди; еще раз нам придется столкнуться с такой ситуацией в главе 10 при реализации семафоров Posix. Упражнения 1. Говоря о листинге 5.4, мы отметили, что атрибут attr функции mq open при создании новой очереди является ненулевым; следует указать оба поля: mq maxmsg и mq msgsi ze. Как можно было бы указать только одно из них, не указывая второе, для которого использовать значения атрибутов по умолчанию? 2. Измените листинг 5.8 так, чтобы при получении сигнала не вызывалась функция mq noti fy. Затем поместите в очередь два сообщения и убедитесь, что для второго из них сигнал порожден не будет. Почему? 3. Измените листинг 5.8 так, чтобы сообщение из очереди при получении сигнала не считывалось. Вместо этого просто вызовите mq notify и напечатайте сообщение о получении сигнала. Затем отправьте два сообщения и убедитесь, что для второго из них сигнал не порождается. Почему? 4. Что произойдет, если мы уберем преобразование двух констант к целому типу в первом вызове printf в листинге 5.14? 5. Измените листинг 5.4 следующим образом: перед вызовом mq open напечатайте сообщение и подождите 30 секунд (sleep). После возвращения из mq open выведите еще одно сообщение и подождите еще 30 секунд, а затем вызовите mq cl ose. Откомпилируйте программу и запустите ее, указав большое количество сообщений (несколько сотен тысяч) и максимальный размер сообщения, скажем, в 10 байт. Задача заключается в том, чтобы создать большую очередь и проверить, используются ли в реализации отображаемые в память файлы. В течение 30-секундной паузы запустите программу типа ps и посмотрите на занимаемый программой объем памяти. Сделайте это еще раз после возвращения из mq open. Можете ли вы объяснить происходящее? 6. Что произойдет при вызове memcpy в листинге 5.26, если вызвавший процесс укажет нулевую длину сообщения? 7. Сравните очередь сообщений с двусторонними каналами, описанными в разделе 4.4. Сколько очередей нужно для двусторонней связи между родительским и дочерним процессами? 8. Почему мы не удаляем взаимное исключение и условную переменную в листинге 5.20? 9. Стандарт Posix утверждает, что дескриптор очереди сообщений не может иметь тип массива. Почему? 10. В каком состоянии проводит большую часть времени функция main из листинга 5.12? Что происходит каждый раз при получении сигнала? Как мы обрабатываем эту ситуацию? И. Не все реализации поддерживают атрибут PTHREAD PROCESS SHARED для взаимных исключений и условных переменных. Переделайте реализацию очередей сообщений из раздела 5.8 так, чтобы использовать семафоры Posix (глава 10) вместо взаимных исключений и условных переменных. 12. Расширьте реализацию очередей сообщений Posix из раздела 5.8 так, чтобы она поддерживала SIGE\/ THREAD. ГЛАВА 6 Очереди сообщений System V 6.1. Введение Каждой очереди сообщений System V сопоставляется свой идентификатор очереди сообщений. Любой процесс с соответствующими привилегиями (раздел 3.5) может поместить сообщение в очередь, и любой процесс с другими соответствующими привилегиями может сообщение из очереди считать. Как и для очередей сообщений Posix, для помещения сообщения в очередь System V не требуется наличия подключенного к ней на считывание процесса. Ядро хранит информацию о каждой очереди сообщений в виде структуры, определенной в заголовочном файле <sys/msg.h>: struct msqidds { struct ipc penn nisg perni; /* Разрешения чтения и записи: раздел 3.3 */ struct msg *msg first; /* указатель на первое сообщение в очереди */ struct msg *msg last: /* указатель на последнее сообщение в очереди */ msglen t msg cbytes; /* размер очереди в байтах */ msgqnum t msg qnum: /* количество сообщений в очереди */ msglen t msg qbytes; /* максимальный размер очереди в байтах */ pid t msgjspid; /* идентификатор (pid) последнего процесса, вызвавшего msgsndO: */ pid t msgjrpid; /* pid последнего msgrcvO: */ time t msg stime; /* время отправки последнего сообщения */ time t msg rtime: /* время последнего считывания сообщения */ time t msg ctime; /* время последнего вызова msgctiО. изменившего одно из полей структуры */ ПРИМЕЧАНИЕ- Unix 98 не требует наличия полей msg first, msgjast и msg cbytes. Тем не менее они имеются в большинстве существующих реализаций, производных от System V. Естественно, ничто не заставляет реализовывать очередь сообщений через связный список, который неявно предполагается при наличии полей msg first и msglast. Эти два указателя обычно указывают на участки памяти, принадлежащие ядру, и практически бесполезны для приложения. Мы можем изобразить конкретную очередь сообщений, хранимую ядром как связный список, - рис. 6.1. В этой очереди три сообщения длиной 1, 2 и 3 байта с типами 100,200 и 300 соответственно. в этой главе мы рассмотрим функции, используемые для работы с очередями сообщений System V, и реализуем наш пример файлового сервера из раздела 4.2 с использованием очередей сообщений.
|
© 2000 - 2024 ULTRASONEX-AMFODENT.RU.
Копирование материалов разрешено исключительно при условии цититирования. |