postmaster.c 中,主循环的大致流程如下:



/*                                    
* Main idle loop of postmaster
*/
static int
ServerLoop(void)
{
......
nSockets = initMasks(&readmask);

for (;;)
{
...
if (pmState == PM_WAIT_DEAD_END)
{
...
}
else
{
...
selres = select(nSockets, &rmask, NULL, NULL, &timeout);
}
...

/* Now check the select() result */
if (selres < 0)
{
if (errno != EINTR && errno != EWOULDBLOCK)
{
......
return STATUS_ERROR;
}
}

/*
* New connection pending on any of our sockets? If so, fork a child
* process to deal with it.
*/
if (selres > 0)
{
int i;

for (i = 0; i < MAXLISTEN; i++)
{
if (ListenSocket[i] == PGINVALID_SOCKET)
break;

if (FD_ISSET(ListenSocket[i], &rmask))
{
Port *port;
port = ConnCreate(ListenSocket[i]);

if (port)
{
BackendStartup(port); /*To fork a new backend */

StreamClose(port->sock);
ConnFree(port);
}
}
}
}

......
}
}


从上面可以看出,基本上是以 C语言的标准select函数 来监听是否有新的连接请求进来。如果有连接请求则调用BackendStartup 函数,开启新的backend 处理连接。

这里面比较令我困惑的是:for (i = 0; i < MAXLISTEN; i++) 循环,对BackendStartup 函数的调用是发生在循环内部。ListenSocket 数组如何理解。需要进一步的研究。