「man select」情報によると:
"On success, select() and pselect() return the number of file descrip‐
tors contained in the three returned descriptor sets which may be zero
if the timeout expires before anything interesting happens. On error,
-1 is returned, and errno is set appropriately; the sets and timeout become
undefined, so do not rely on their contents after an error."
次の理由により、Select はウェイクアップします。
1)read/write availability
2)select error
3)descriptoris closed.
しかし、利用可能なデータがなく、選択がまだタイムアウト内にある場合、どうすれば別のスレッドから select() を起こすことができますか?
[更新]
疑似コード
// Thread blocks on Select
void *SocketReadThread(void *param){
...
while(!(ReadThread*)param->ExitThread()) {
struct timeval timeout;
timeout.tv_sec = 60; //one minute
timeout.tv_usec = 0;
fd_set rds;
FD_ZERO(&rds);
FD_SET(sockfd, &rds)'
//actually, the first parameter of select() is
//ignored on windows, though on linux this parameter
//should be (maximum socket value + 1)
int ret = select(sockfd + 1, &rds, NULL, NULL, &timeout );
//handle the result
//might break from here
}
return NULL;
}
//main Thread
int main(){
//create the SocketReadThread
ReaderThread* rthread = new ReaderThread;
pthread_create(&pthreadid, NULL, SocketReaderThread,
NULL, (void*)rthread);
// do lots of things here
............................
//now main thread wants to exit SocketReaderThread
//it sets the internal state of ReadThread as true
rthread->SetExitFlag(true);
//but how to wake up select ??????????????????
//if SocketReaderThread currently blocks on select
}
[UPDATE]
1) @trojanfoe はこれを達成する方法を提供します。彼の方法はソケット データ (ダーティ データまたは終了メッセージ データの可能性があります) をウェイクアップ セレクトに書き込みます。テストを行い、そこで結果を更新します。
2)もう1つ言及することは、ソケットを閉じてもselect関数呼び出しが起動することを保証するものではありません。この投稿を参照してください。
[UPDATE2]多くのテストを行った後、selectの
ウェイクアップに関するいくつかの事実を以下に
示します。これ以降、ソケットからの読み取りまたはソケットへの書き込みは、errno = 0 で 0 の戻り値を取得します
2) select によって監視されているソケットが同じアプリケーションの別のスレッドによって閉じられている場合、select() は読み書きするデータはありません。select のタイムアウト後、読み取り/書き込み操作を行うと、errno = EBADF のエラーが発生します (タイムアウト期間中に別のスレッドによってソケットが閉じられたため)。