バージョンごとのドキュメント一覧

34.9. 非同期通知 #

<title>Asynchronous Notification</title>

<productname>PostgreSQL</productname> offers asynchronous notification via the <command>LISTEN</command> and <command>NOTIFY</command> commands. A client session registers its interest in a particular notification channel with the <command>LISTEN</command> command (and can stop listening with the <command>UNLISTEN</command> command). All sessions listening on a particular channel will be notified asynchronously when a <command>NOTIFY</command> command with that channel name is executed by any session. A <quote>payload</quote> string can be passed to communicate additional data to the listeners. PostgreSQLは、LISTENNOTIFYコマンドを使用した、非同期通知をサポートします。 クライアントセッションは、LISTENコマンドを使用して処理対象とする特定の通知チャネルを登録します。 (通知監視を取り止めるにはUNLISTENコマンドを使用します。) 任意のセッションでそのチャネル名によるNOTIFYコマンドが実行されると、特定チャネルを監視しているすべてのセッションは非同期に通知を受け取ります。 監視者に追加データを通信するためにペイロード文字列を渡すことができます。

<application>libpq</application> applications submit <command>LISTEN</command>, <command>UNLISTEN</command>, and <command>NOTIFY</command> commands as ordinary SQL commands. The arrival of <command>NOTIFY</command> messages can subsequently be detected by calling <function id="libpq-PQnotifies">PQnotifies</function>.<indexterm><primary>PQnotifies</primary></indexterm> libpqアプリケーションは、通常のSQLによる問い合わせと同じようにLISTENUNLISTENおよびNOTIFYコマンドを発行することができます。 NOTIFYメッセージの到着は、続いてPQnotifies.を呼び出せば検出できます。

The function <function>PQnotifies</function> returns 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 <function>PQnotifies</function>, it is considered handled and will be removed from the list of notifications. PQnotifies関数は、サーバから受信した通知メッセージの未処理リストから次の通知を返します。 保留中の通知がなくなればNULLポインタを返します。 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 */

    char *relname;              /* 通知チャネル名 */
    int  be_pid;                /* 通知元サーバプロセスのプロセスID */
    char *extra;                /* 通知ペイロード文字列 */
} PGnotify;

After processing a <structname>PGnotify</structname> object returned by <function>PQnotifies</function>, be sure to free it with <xref linkend="libpq-PQfreemem"/>. It is sufficient to free the <structname>PGnotify</structname> pointer; the <structfield>relname</structfield> and <structfield>extra</structfield> fields do not represent separate allocations. (The names of these fields are historical; in particular, channel names need not have anything to do with relation names.) PQnotifiesで返されたPGnotifyオブジェクトの処理が終わったら、PQfreememを使用して確実に解放してください。 PGnotifyポインタを解放することは重要です。 relnameextraフィールドは別の割り当てを表していません。 (これらのフィールド名は歴史的なものです。特にチャネル名はリレーション名と関係するものである必要はありません。)

<xref linkend="libpq-example-2"/> gives a sample program that illustrates the use of asynchronous notification. 例 34.2で非同期通知を使用したサンプルプログラムを示しています。

<function>PQnotifies</function> does not actually read data from the server; it just returns messages previously absorbed by another <application>libpq</application> function. In ancient releases of <application>libpq</application>, the only way to ensure timely receipt of <command>NOTIFY</command> messages was to constantly submit commands, even empty ones, and then check <function>PQnotifies</function> after each <xref linkend="libpq-PQexec"/>. While this still works, it is deprecated as a waste of processing power. PQnotifiesは実際にサーバのデータを読み出すわけではありません。 これは単に、他のlibpq関数が吸収してしまっていた通知メッセージを返すだけです。 libpqの古いリリースでは、NOTIFYメッセージを適切な時点で確実に受け取るには、空の問い合わせでも何でも、とにかく一定時間ごとに問い合わせを送り、そしてPQexecを実行するたびにPQnotifiesを検査するしかありませんでした。 今でもこの方法は動作しますが、処理能力の無駄使いをすることになるのでやめておくべきでしょう。

A better way to check for <command>NOTIFY</command> messages when you have no useful commands to execute is to call <xref linkend="libpq-PQconsumeInput"/>, then check <function>PQnotifies</function>. You can use <function>select()</function> to wait for data to arrive from the server, thereby using no <acronym>CPU</acronym> power unless there is something to do. (See <xref linkend="libpq-PQsocket"/> to obtain the file descriptor number to use with <function>select()</function>.) Note that this will work OK whether you submit commands with <xref linkend="libpq-PQsendQuery"/>/<xref linkend="libpq-PQgetResult"/> or simply use <xref linkend="libpq-PQexec"/>. You should, however, remember to check <function>PQnotifies</function> after each <xref linkend="libpq-PQgetResult"/> or <xref linkend="libpq-PQexec"/>, to see if any notifications came in during the processing of the command. 実行すべき問い合わせがない時にNOTIFYメッセージを検査するよい方法は、まずPQconsumeInput を呼び出し、それからPQnotifiesを検査することです。 サーバからのデータの到着をselect()で待つことができ、不必要な動作でCPUパワーを消費してしまうことがありません。 (select()で使用するファイル記述子番号の取得については、PQsocketを参照してください。) なお、これは問い合わせにPQsendQueryPQgetResultを使った時でも、またはおなじみのPQexecを使った時でも動作します。 しかし通知がコマンドの処理中に届いていないかどうか、PQgetResultあるいはPQexecの実行ごとにPQnotifiesを調べることを忘れないようにしておくべきです。