2

这里开始,它说它select()用于“监视多个文件描述符,等待一个或多个文件描述符为某种类型的 I/O 操作(例如,可能的输入)“准备好”。然后我看了一下Beej的socket编程指南,他们用来select()监控socket文件描述符。

简而言之,教程和手册页说select()文件描述符进行操作。但是,我遇到了一段select()用于监视对象的代码。代码:

class SomeObject
{
    public:
        static SomeObject *_pInstance;
        //...some other methods...
}

SomeObject *SomeObject::_pInstance = new SomeObject();    
SomeObject &refObj = *SomeObject::_pInstance;
fd_set fdAllSet, fdReadableSet;
int nReadyHandles = 0;

FD_SET( refObj, &fdAllsSet ); //<---this line

while (1)
{
    fdReadableSet = fdAllSet;

    nReadyHandles = select( maxFd+1, &fdReadableSet, NULL, NULL, &someWaitTime );

    while (nReadyHandles > 0)
    {
        if (FD_ISSET(refObj, &fdReadableSet))
        {//do something
            FD_CLR(refObj, &fdReadableSet);
        }
    }
}

所以问题是,如何select()确定我的“对象是否准备好”?为什么FD_SET()不给出任何编译错误,因为第一个参数假设是 anint而不是refObj

4

3 回答 3

3

FD_SET 和朋友们将整数作为第一个参数......

void FD_CLR(int fd, fd_set *set);
int  FD_ISSET(int fd, fd_set *set);
void FD_SET(int fd, fd_set *set);

因此,您的代码可以编译的唯一方法是(a)SomeObject 具有SomeObject::operator int()返回文件描述符的用户定义转换运算符:

class SomeObject
{
    int my_fd;

    operator int() { return my_fd; }
};

或 (b) FD_* 操作被定义为真正的函数(而不是宏),并且有用户定义的 FD_* 重载,它们采用 SomeObject 并将它们提取/映射到 fd,然后调用原始系统版本:

void FD_CLR(const SomeObject& so, fd_set *set)
{
    FD_CLR(so.my_fd, set);
}

int  FD_ISSET(const SomeObject& so, fd_set *set)
{
    return FD_ISSET(so.my_fd, set);
}

void FD_SET(const SomeObject& so, fd_set *set)
{
    return FD_SET(so.my_fd, set);
}
于 2012-04-17T06:52:22.717 回答
2

猜测一下,该类SomeObject有一个强制转换为整数的重载,它返回一个文件描述符,无论它做什么。

于 2012-04-17T06:50:16.397 回答
-1

select() 和 FD_SET 作用于文件描述符,它们实际上是整数,而不是指向“SomeObject”的指针。

于 2012-04-17T06:55:33.957 回答