Top > C言語 > select


リニューアル

サイトリニューアル中です。本ページは以下URLへ移動しました。
Prog.さな雑記

関数仕様

機能
複数のファイルディスクリプタを同時に監視する
書式
すべてを展開すべてを収束
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
/* POSIX.1.2001 に従う場合 */
#include <sys/select.h>
 
/* 以前の規格に従う場合 */
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
 
int select (int nfds, fd_set *readfds, fd_set *writefds,
            fd_set *exceptfds, struct timeval *timeout);
 
void FD_CLR (int fd, fd_set *fds);
int FD_ISSET (int fd, fd_set *fds);
void FD_SET (int fd, fd_set *fds);
void FD_ZERO (fd_set *fds);
引数
引数名説明
nfds3つの集合(readfds,writefds,exceptfds)に含まれるファイルディスクリプタの最大値に 1 を足したもの
readfds読み出しが可能かどうかを監視するファイルディスクリプタの集合へのポインタ or NULL
writefds書込みが可能かどうかを監視するファイルディスクリプタの集合へのポインタ or NULL
exceptfds例外が発生したかどうかを監視するファイルディスクリプタの集合へのポインタ or NULL
timeroutTimeout になる時間を指定する timeval 構造体へのポインタ (NULL の場合は無期限)
fdsファイルディスクリプタの集合へのポインタ
fdファイルディスクリプタ
戻り値
正の値 : 変化があったファイルディスクリプタの総数(readfds,writefds,exceptfds)
     0 : Timeout
    -1 : エラーが発生
エラー
errno内容
EBADF何れかの集合に無効なファイルディスクリプタが指定された
EINTRシグナルを受信した
EINVALtimeout に入っている値を含め、値が不正である
ENOMEM内部テーブルにメモリを割り当てることができなかった

集合を扱う為のマクロ

関数名内容
FD_CLR ()集合(fds)にセットされているファイルディスクリプタ(fd)を、集合から削除する
FD_ISSET ()集合(fds)にファイルディスクリプタがあるかどうか調べる。このマクロは select() が終了した後に使うと便利
FD_SET ()集合(fds)に、ファイルディスクリプタ(fd)をセットする
FD_ZERO ()集合(fds)を削除する

注意

Linux では、select() は timeout を変更し、 残りの停止時間を反映するようになっている。 しかし、他のほとんどの実装はこのようになっていない (POSIX.1-2001はどちらの動作も認めている)。
このため、timeout を参照している Linux のコードを 他の OS へ移植する場合、問題が起こる。 select() から復帰した後、timeout は未定義であると考えるべきである。

サンプル

すべてを展開すべてを収束
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 
 
 
 
 
 
 
 
 
 
 
 
 
 
-
|
|
|
|
|
|
|
|
|
-
|
!
|
|
|
-
|
!
|
|
-
|
|
|
|
|
|
|
|
|
|
|
-
|
|
|
|
!
|
-
|
!
|
-
|
-
|
!
|
-
|
!
!
!
|
|
|
|
|
|
|
|
|
|
|
!
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
 
#define MYSQL_SOCKET "/tmp/mysql.sock"
#define CLAMD_SOCKET "/tmp/clamd.sock"
 
#define max(a,b)     ((a >= b) ? a : b)
 
int
main (void)
{
  int mysql_fd = -1;
  int clamd_fd = -1;
  int maxfd = -1;
  fd_set fds;
  struct timeval tv;
  int ret;
 
  mysql_fd = open (MYSQL_SOCKET, O_RDONLY);
  if (mysql_fd < 0)
    {
      goto error;
    }
 
  clamd_fd = open (CLAMD_SOCKET, O_RDONLY);
  if (clamd_fd < 0)
    {
      goto error;
    }
 
  while (1)
    {
      FD_ZERO (&fds);
      FD_SET (mysql_fd, &fds);
      maxfd = max (maxfd, mysql_fd);
      FD_SET (clamd_fd, &fds);
      maxfd = max (maxfd, clamd_fd);
 
      tv.tv_sec = 5;
      tv.tv_usec = 0;
 
      ret = select (maxfd + 1, &fds, NULL, NULL, &tv);
      if (ret < 0)               /* error */
        {
          if (errno == EINTR)    /* signal */
            continue;
          else
            goto error;
        }
      else if (ret == 0)         /* timeout */
        {
          continue;
        }
      else
        {
          if (FD_ISSET (mysql_fd, &fds))
            {
              /* 処理を書く */
            }
          if (FD_ISSET (clamd_fd, &fds))
            {
              /* 処理を書く */
            }
        }
    }
 
  close (mysql_fd);
  close (clamd_fd);
  _exit (0);
 
 error:
  if (mysql_fd >= 0)
    close (mysql_fd);
  if (clamd_fd >= 0)
    close (clamd_fd);
  _exit (1);
}

リロード   凍結解除 コピー 名前変更   ホーム 一覧 検索 最終更新 バックアップ リンク元   ヘルプ   最終更新のRSS
Last-modified: Sun, 02 Jan 2022 11:56:29 UTC (991d)