Redrock Postgres 搜索 英文
版本: 9.3 / 9.4 / 9.5 / 9.6 / 10 / 11 / 12 / 13 / 14 / 15 / 16 / 17

32.9. 异步通知 #

PostgreSQL 通过 LISTENNOTIFY 命令提供异步通知。客户端会话使用 LISTEN 命令注册其对特定通知频道感兴趣(可以使用 UNLISTEN 命令来停止监听)。当任何会话执行带有该频道名称的 NOTIFY 命令时,监听特定频道的会话都将异步收到通知。可以传递 payload 字符串来向监听器通信附加数据。

libpq 应用程序将 LISTENUNLISTENNOTIFY 命令作为普通 SQL 命令提交。随后可以通过调用 PQnotifies 来检测 NOTIFY 消息的到达。

函数 PQnotifies 从从服务器接收的一系列未处理通知消息中返回下一个通知。如果没有待处理的通知,它将返回一个空指针。一旦从 PQnotifies 返回通知,就认为该通知已被处理,并将从通知列表中删除。

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;

在处理 PQnotifies 返回的 PGnotify 对象后,务必使用 PQfreemem 来释放它。释放 PGnotify 指针已足够;relnameextra 字段没有用作单独的分配。(这些字段的名称具有历史意义;特别是,频道名称无需与关系名称有任何关系。)

示例 32.2 提供了一个示例程序,该程序说明如何使用异步通知。

PQnotifies 实际上不会从服务器读取数据;它只返回之前已由另一个 libpq 函数吸收的消息。在 libpq 的旧版本中,确保及时接收 NOTIFY 消息的唯一方法是提交命令(甚至是空命令),然后在每次 PQexec 后检查 PQnotifies。虽然这仍然有效,但由于浪费处理能力而不赞成这种做法。

当您没有要执行的有用命令时,检查 NOTIFY 消息的一个更好的方法是调用 PQconsumeInput,然后再检查 PQnotifies。您可以使用 select() 来等待来自服务器的数据,从而不使用CPU没有要执行的任务时,不使用电源。(请参阅 PQsocket 获取使用 select() 的文件描述符编号。)请注意,无论您使用 PQsendQuery/PQgetResult 提交命令,还是仅仅使用 PQexec,这都可以正常运行。但是,您应该在每次 PQgetResultPQexec 之后记住检查 PQnotifies,以查看在处理命令期间是否收到了任何通知。