Документация по PostgreSQL 9.4.1 | |||
---|---|---|---|
Пред. | Уровень выше | Глава 31. libpq — библиотека для языка C | След. |
31.8. Асинхронное уведомление
PostgreSQL предлагает асинхронное уведомление посредством команд LISTEN и NOTIFY. Клиентский сеанс работы регистрирует свою заинтересованность в конкретном канале уведомлений с помощью команды LISTEN (и может остановить прослушивание с помощью команды UNLISTEN). Все сеансы, прослушивающие конкретный канал, будут уведомляться в асинхронном режиме, когда в рамках любого сеанса команда NOTIFY выполняется с параметром, указывающим имя этого канала. Для передачи дополнительных данных прослушивающим сеансам может использоваться строка "payload".
Приложения, использующие libpq, отправляют серверу команды LISTEN, UNLISTEN и NOTIFY, как обычные SQL-команды. Прибытие сообщений от команды NOTIFY можно впоследствии обнаружить с помощью вызова функции PQnotifies
.
Функция PQnotifies
возвращает следующее уведомление из списка необработанных уведомительных сообщений, полученных от сервера. Она возвращает нулевой указатель, если нет уведомлений, ожидающих обработки. Как только уведомление возвращено из функции PQnotifies
, оно считается обработанным и будет удалено из списка уведомлений.
PGnotify *PQnotifies(PGconn *conn); typedef struct pgNotify { char *relname; /* имя канала уведомлений */ int be_pid; /* ID серверного процесса, посылающего уведомление */ char *extra; /* строка сообщения в уведомлении */ } PGnotify;
После обработки объекта PGnotify, возвращённого функцией PQnotifies
, обязательно освободите память, занимаемую им, с помощью функции PQfreemem
. Достаточно освободить указатель на PGnotify; поля relname и extra не представляют отдельных областей памяти. (Имена этих полей являются таковыми по историческим причинам; в частности, имена каналов не обязаны иметь ничего общего с именами реляционных отношений.)
Пример 31-2 представляет пример программы, иллюстрирующей использование асинхронного уведомления.
Функция PQnotifies
в действительности не читает данные с сервера; она просто возвращает сообщения, предварительно собранные другой функцией библиотеки libpq. В предшествующих выпусках libpq единственным способом обеспечения своевременного получения сообщений от команды NOTIFY была постоянная отправка команд, даже пустых, а затем проверка PQnotifies
после каждого вызова PQexec
. Хотя этот метод все ещё работает, он не рекомендуется, поскольку растрачивает впустую процессорное время.
Более хорошим способом проверки наличия сообщений от команды NOTIFY, когда у вас нет полезных команд для выполнения, является вызов функции PQconsumeInput
с последующей проверкой PQnotifies
. Вы можете использовать select()
, чтобы подождать прибытия данных с сервера, тем самым не используя мощности CPU, если нет полезной работы. (См. PQsocket
насчёт получения номера файлового дескриптора для использования его с select()
.) Обратите внимание, что это будет хорошо работать, независимо от того, отправляете ли вы команды с помощью PQsendQuery
/PQgetResult
или просто используете PQexec
. Следует, однако, не забывать проверять PQnotifies
после каждого вызова PQgetResult
или PQexec
, чтобы увидеть, не прибыли ли какие-либо уведомления в процессе обработки команды.
Пред. | Начало | След. |
Интерфейс быстрого пути | Уровень выше | Функции, связанные с командой COPY |