async.c的 ?
static void?
NotifyMyFrontEnd(const char *channel, const char *payload, int32 srcPid) 函數中的主要邏輯是這樣的:
復制代碼
if (whereToSendOutput == DestRemote)?
{ ? ?
StringInfoData buf; ? ?
pq_beginmessage(&buf, 'A'); ? ? //cursor 為 A ? ?
pq_sendint(&buf, srcPid, sizeof(int32)); //追加 srcPid ? ?
pq_sendstring(&buf, channel); ? ? //追加消息通道名 ? ?
if (PG_PROTOCOL_MAJOR(FrontendProtocol) >= 3) ? ?
pq_sendstring(&buf, payload); ? ? //追加消息字節流 ? ?
pq_endmessage(&buf); ? ? //發送消息
...... ? ?
}
復制代碼
從上面看到,向StringInfoData 數據結構填充信息,就表示信息發送結束。
static void?
NotifyMyFrontEnd(const char *channel, const char *payload, int32 srcPid)
pq_endmessage是 pqformat.c 中函數它 調用 pqcomm.c 中的 pq_putmessage函數
pq_putmessage 調用 internal_putbyes函數
internal_putbyes 中 對pqSendPointer 進行操作
關于 pqSendPointer/pqRevPointer,有如下定義:
--------------------------------------------------------------------------------------------
static char PqSendBuffer[PQ_BUFFER_SIZE];
static int PqSendPointer; /* Next index to store a byte in PqSendBuffer */
static char PqRecvBuffer[PQ_BUFFER_SIZE];
static int c; /* Next index to read a byte from PqRecvBuffer */
static int PqRecvLength; /* End of data available in PqRecvBuffer */
---------------------------------------------------------------------------------------------
查閱文檔資料:《PostgreSQL數據庫內核分析》中2.6.6中也有所說明。
從 internal_putbyes 中的代碼邏輯看到,移動指針未加任何鎖定機制。
復制代碼
static int ? ?
internal_putbytes(const char *s, size_t len) ? ?
{ ? ?
size_t ? ? amount; ? ?
while (len > 0) ? ?
{ ? ?
/* If buffer is full, then flush it out */ ? ?
if (PqSendPointer >= PQ_BUFFER_SIZE) ? ?
if (internal_flush()) ? ?
return EOF;
amount = PQ_BUFFER_SIZE - PqSendPointer; ? ?
if (amount > len) ? ?
amount = len;
memcpy(PqSendBuffer + PqSendPointer, s, amount); ? ?
PqSendPointer += amount; ? ?
s += amount; ? ?
len -= amount; ? ?
} ? ?
return 0; ? ?
} ? ?
復制代碼
既然未加鎖,那么就可以這樣推斷:
在每一對客戶端和服務器端進程之間,都有這樣一個內存緩沖區。
換句話說,有多少個客戶端,就會產生多少個這樣的 內存緩沖區。
具體如何,還需進一步的驗證。
本文轉自健哥的數據花園博客園博客,原文鏈接:http://www.cnblogs.com/gaojian/archive/2012/07/17/2594718.html,如需轉載請自行聯系原作者