# 34.9. Asynchronous Notification

PostgreSQL offers asynchronous notification via theLISTENandNOTIFYcommands. A client session registers its interest in a particular notification channel with theLISTENcommand (and can stop listening with theUNLISTENcommand). All sessions listening on a particular channel will be notified asynchronously when aNOTIFYcommand with that channel name is executed by any session. A “payload” string can be passed to communicate additional data to the listeners.

libpq applications submitLISTEN,UNLISTEN, andNOTIFYcommands as ordinary SQL commands. The arrival ofNOTIFYmessages can subsequently be detected by callingPQnotifies.

The functionPQnotifiesreturns the next notification from a list of unhandled notification messages received from the server. It returns a null pointer if there are no pending notifications. Once a notification is returned from通知,则视为已处理,并将从通知列表中删除。

PGnotify *PQnotifies(PGconn *conn);

typedef struct pgNotify
{
    char *relname;              /* notification channel name */
    int  be_pid;                /* process ID of notifying server process */
    char *extra;                /* notification payload string */
} PGnotify;

处理完一个PGnotify返回的对象通知,一定要用PQfreemem.这就足够释放PGnotify指针;这个重新命名额外的字段不代表单独的分配。(这些字段的名称是历史的;尤其是通道名称不需要与关系名称有任何关系。)

例34.2给出了一个示例程序,演示了异步通知的使用。

通知实际上不从服务器读取数据;它只返回以前被另一个libpq函数吸收的消息。在古代版本的libpq中,确保及时收到通知信息是不断提交命令,甚至是空命令,然后检查通知每次之后PQexec。虽然这仍然有效,但它被认为是一种浪费处理能力的做法。

一种更好的检查通知当您没有要执行的有用命令时的消息是调用PQconsume输入,然后检查PQ 通知.您可以使用选择()等待数据从服务器到达,因此除非有事可做,否则不会使用 CPU 功率。(看PQsocket获取要使用的文件描述符编号选择().) 请注意,无论您使用以下命令提交命令,这都可以正常工作PQsendQuery/PQgetResult或简单地使用执行程序.但是,您应该记得检查PQ 通知每次之后PQgetResult要么执行程序,查看在命令处理过程中是否有任何通知进来。