我在閱讀libpq
參考。它具有同步和異步方法。我發現了一些奇怪的東西。爲什麼`libpq`使用輪詢而不是通知來獲取數據?
當我看到PQsendQuery
函數時,它似乎發送一個查詢並立即返回。我希望有一個回調函數來獲得通知,但是沒有這樣的事情,並且手冊說輪詢的數據可用性。
我不明白爲什麼異步方法是以輪詢方式編寫的。無論如何,因爲libp
是官方的客戶端實現,我相信這個設計應該有一個很好的理由。那是什麼?或者我錯過了在其他地方提到的正確回調的東西?
我在閱讀libpq
參考。它具有同步和異步方法。我發現了一些奇怪的東西。爲什麼`libpq`使用輪詢而不是通知來獲取數據?
當我看到PQsendQuery
函數時,它似乎發送一個查詢並立即返回。我希望有一個回調函數來獲得通知,但是沒有這樣的事情,並且手冊說輪詢的數據可用性。
我不明白爲什麼異步方法是以輪詢方式編寫的。無論如何,因爲libp
是官方的客戶端實現,我相信這個設計應該有一個很好的理由。那是什麼?或者我錯過了在其他地方提到的正確回調的東西?
在單線程程序的執行模型中,執行流程不能被異步查詢返回的數據或更一般的網絡套接字中斷。只有信號(SIGTERM
和朋友)可能會中斷流量,但信號不能掛接到數據進入。
這就是爲什麼有一個回調來獲取傳入數據的通知是不可能的。如果你的代碼沒有調用它,那麼libpq中用於發出回調所需的代碼永遠不會運行。如果你不得不稱呼它,那就會挫敗回調的全部。
有類似Qt
這樣的庫提供回調,但是它們是從頭開始架構的,具有充當事件處理器的主循環。用戶代碼在回調中進行組織,並且可以對傳入數據進行基於事件的處理。但在這種情況下,該庫將獲取執行流程的所有權,這意味着它的主循環會輪詢數據源。這只是將職責轉移到libpq之外的另一段代碼。
此頁面描述如何獲得異步結果獲取的通知。
http://www.postgresql.org/docs/9.3/static/libpq-events.html#LIBPQ-EVENTS-PROC
PGEVT_RESULTCREATE
結果創建事件是響應燒製以任何查詢執行 功能,其產生的結果,其中包括PQgetResult時。此事件 只有在結果成功創建後纔會被觸發。
typedef struct { PGconn * conn; PGresult * result; } PGEventResultCreate;當收到PGEVT_RESULTCREATE事件時,evtInfo指針應該轉換爲 PGEventResultCreate *。 conn是用於生成 結果的連接。這是初始化 需要與結果關聯的任何實例數據的理想位置。如果事件過程失敗, 結果將被清除並且失敗將被傳播。 事件過程不得嘗試PQclear自己的結果對象。 當返回失敗代碼時,必須執行所有清理,因爲不會發送 PGEVT_RESULTDESTROY事件。
這並不會改變'PQsendQuery'之後的輪詢需求。如果你不這樣做,這個事件將永遠不會被解僱。 –
只是稍後註釋:'libpq'具有'PQsocket'函數,該函數返回*套接字的文件描述符*。要通知數據可用性,請使用系統API監視此套接字。 ('kqueue','libdispatch'等) – Eonil
現在我終於明白了這個設計。這只是阻塞與非阻塞*風格*的區別,API的形式對性能來說並不重要。 – Eonil