来自here,它表示select()
用于“监视多个文件描述符,等待一个或多个文件描述符为某些I / O操作类”准备好“(例如,输入可能)“。然后我查看Beej's guide for socket programming,他们使用select()
来监视套接字文件描述符。
简而言之,教程和手册页说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()
没有给出任何编译错误,因为第一个参数假设是int
而不是refObj
?
答案 0 :(得分: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);
}
答案 1 :(得分:2)
猜测,类SomeObject
有一个重载,用于强制转换为整数,它返回一个文件描述符,无论它做什么。
答案 2 :(得分:-1)
select()和FD_SET处理文件描述符,它们实际上是整数,而不是指向“SomeObject”的指针。