【问题标题】:How can I use select() to monitor an object?如何使用 select() 来监视对象?
【发布时间】:2012-04-17 06:38:21
【问题描述】:

来自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?

【问题讨论】:

  • 也许,FD_SET 宏被重新定义为使用 SomeObject 的 FD 成员!?你从哪里得到这个代码?
  • 您需要向我们展示class SomeObject 的完整 声明,以了解其工作原理。为了让它工作,它必须包装一个文件描述符;看看它是如何工作的会很有趣......

标签: c++ linux networking


【解决方案1】:

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);
}

【讨论】:

  • 谢谢! SomeObject::operator int() 确实超载了! operator int()实际上返回了一个打开的驱动的文件描述符。
  • FD_SET 等可能不是正确的函数,而是使用预处理器定义的宏。在这种情况下,它们不能被重载。
  • @JoachimPileborg:是的,至少在 Linux 上它们被定义为宏。添加了说明。
【解决方案2】:

据推测,SomeObject 类有一个重载,用于强制转换为整数,无论​​它做什么,它都会返回一个文件描述符。

【讨论】:

    【解决方案3】:

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

    【讨论】:

      猜你喜欢
      • 2013-06-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-04
      • 1970-01-01
      • 2022-07-16
      • 1970-01-01
      相关资源
      最近更新 更多