0

我很确定人们会很难回答这个问题,说这是一个重复的问题。但我打算问一些具体的事情。我遇到了这样一个场景,其中一个 select 调用无法获得句柄,而 poll 系统调用可以识别句柄。

我没有找到任何令人欣慰的理由。让我解释一下这个场景——我试图让一个 scocket 客户端注册到不在同一台机器上的服务器。当客户端在同一台机器上时,选择系统调用可以有效地工作。但是当它不是同一台机器的一部分时,它会失败并且轮询工作。

这背后有什么普遍的共鸣吗?(注意:我正在使用 ACE 包装库)添加的代码片段

           int noOfHandles = 4;
            int handles[4];

            int result = thedserver->get_handles(handles,noOfHandles);

            if ((result < 0 ) || (noOfHandles <= 0))
            {
                    return -1;
            }
            ACE_Handle_Set dsdHandleSet;

            for( int i = 0 ;  i < noOfHandles ; i++)
            {
                    cout << "handles: " << handles[i] << endl;
                    dsdHandleSet.set_bit(handles[i]);
            }
            cout << "noOfHandles: " << noOfHandles << endl;
            ACE_Time_Value tv1(60, 0);

            while(1)
            {
                    int res = ACE::select(dsdHandleSet.max_set() + 1, &dsdHandleSet, 0, 0,&tv1);
                    cout << "res: " << res << endl;
            } 
4

3 回答 3

2

我想我不确定您的代码要做什么。我不知道你为什么要while(1)选择功能,但这里有很多问题。确保你阅读了select()的 man

首先,您设置了超时。如果您想永远等到句柄准备好,请传递NULL超时值。

其次,每次运行后,select()修改超时时间,所以你想使用它,你必须重写它。您可以使用pselect()来避免这种情况。

最后,您应该在调用 select 之前使用FD_ZERO()andFD_SET()来清除和设置文件描述符。

其中一些可能是在 ACE 库中为您抽象出来的,我对此并不熟悉,但总的来说,这些是我看到的错误/缺失的部分。

于 2012-11-01T11:51:03.283 回答
1

我怀疑您的代码中有错误,或者文件描述符不在 FD_SETSIZE 之外(这将是代码中的错误)。在我研究过如何实现 select/poll 的系统上,select 是通过将内核内部的参数转换为等效的 poll 调用来实现的(在旧系统上反之亦然)。换句话说 - 应该没有功能差异。

于 2012-11-01T11:34:41.933 回答
1

我不确定 ACE 库,但select系统调用修改了它的参数。您需要在每次调用select循环之前重新创建集合。

于 2012-11-01T11:42:59.067 回答