2

ここからは、select()「複数のファイル記述子を監視し、1つ以上のファイル記述子が何らかのクラスのI / O操作(入力可能など)に対して「準備完了」になるまで待機する」ために使用されます。次に、ソケットプログラミングに関するBeejのガイド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ですか?

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_ *操作が(マクロではなく)実際の関数として定義されており、SomeObjectを取得してそれらをfdに抽出/マップしてから、元のシステムバージョンを呼び出す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 に答える