对postmaster.c 中的 readmask,rmask,nsocket等进行分析,可以看到:它们之间有如下的关系(与细节无关的代码省略):
复制代码
/*
* Initialise the masks for select() for the ports we are listening on.
* Return the number of sockets to listen on.
*/
static int
initMasks(fd_set *rmask)
{
int maxsock = -1;
int i;
FD_ZERO(rmask);
for (i = 0; i < MAXLISTEN; i++)
{
int fd = ListenSocket[i];
if (fd == PGINVALID_SOCKET)
break;
FD_SET(fd, rmask);
if (fd > maxsock)
maxsock = fd;
}
return maxsock + 1;
}
复制代码
和
复制代码
static int
ServerLoop(void)
{
......
nSockets = initMasks(&readmask);
for (;;)
{
fd_set rmask;
int selres;
/*
* Wait for a connection request to arrive.
* We wait at most one minute, to ensure that the other background
* tasks handled below get done even when no requests are arriving.
* If we are in PM_WAIT_DEAD_END state, then we don't want to accept
* any new connections, so we don't call select() at all; just sleep
* for a little bit with signals unblocked.
*/
memcpy((char *) &rmask, (char *) &readmask, sizeof(fd_set));
PG_SETMASK(&UnBlockSig);
if (pmState == PM_WAIT_DEAD_END)
{
...
}
else
{
...
selres = select(nSockets, &rmask, NULL, NULL, &timeout);
}
/*
* Block all signals until we wait again. (This makes it safe for our
* signal handlers to do nontrivial work.)
*/
PG_SETMASK(&BlockSig);
/* Now check the select() result */
if (selres < 0)
{
...
}
/*
* New connection pending on any of our sockets? If so, fork a child
* process to deal with it.
*/
if (selres > 0)
{
...
}
...
}
}
复制代码
可以看出来,nsocket就是用于监听网络通信的地 fd_set中的文件描述符最大值+1。
至于原始的文件描述符,就是来自于 ListenSocket数组。
为了进一步研究,还需要从源头上看ListenSocket是如何被赋值的。
本文转自健哥的数据花园博客园博客,原文链接:http://www.cnblogs.com/gaojian/archive/2012/07/20/2601081.html,如需转载请自行联系原作者