Unix-system-calls--newselect

提供:Dev Guides
移動先:案内検索

[top]#

|http://www.google.com/[Google] | a|

Web This Site
  • 初心者向けのUnix *
  • 高度なUnix *

選択した読書

Copyright©2014 by finddevguides

[cols=",,,,,,,",]

| |  Home   | |  References   | |  Discussion Forums   | |  About TP  

[width="100%",cols="100%",]

a| == select()-Unix、Linuxシステムコール

[[File:]] image :http://www.finddevguides.com/images/next.gif [next] image:http://www.finddevguides.com/add- this.gif [AddThisソーシャルブックマークボタン]

広告

NAME

select、pselect、FD_CLR、FD_ISSET、FD_SET、FD_ZERO-同期I/O多重化

概要

/*According to POSIX.1-2001*/ #include <sys/select.h> /*According to earlier standards*/ #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 *set); int FD_ISSET(int fd, fd_set *set); void FD_SET(int fd, fd_set *set); void FD_ZERO(fd_set *set); #define _XOPEN_SOURCE 600 #include <sys/select.h> int pselect(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, const struct timespec *timeout, const sigset_t *sigmask);

説明

*select* ()および *pselect* ()を使用すると、プログラムは複数のファイル記述子を監視し、1つまたは複数のファイル記述子がI/O操作のクラス(入力可能など)の「準備完了」になるまで待機できます。 ブロックせずに対応するI/O操作(たとえば、 *read* (2))を実行できる場合、ファイル記述子は準備完了と見なされます。
*select* ()と *pselect* ()の操作は同じですが、3つの違いがあります。
S.N. Description
(i) select() uses a timeout that is a struct timeval (with seconds and microseconds), while pselect() uses a struct timespec (with seconds and nanoseconds).
(ii) select() may update the timeout argument to indicate how much time was left. pselect() does not change this argument.
(iii) select() has no sigmask argument, and behaves as pselect() called with NULL sigmask.

ファイル記述子の3つの独立したセットが監視されます。 readfds_にリストされているものは、文字が読み取り可能になるかどうかを監視します(より正確には、読み取りがブロックされないかどうかを確認します;特に、ファイル記述子もファイルの終わりで準備できます)、 writefds_内の文字は書き込みがブロックされないかどうかを見るために監視され、_exceptfds_内の例外は監視されます。 終了時に、セットはその場で変更され、どのファイル記述子が実際にステータスを変更したかを示します。 対応するクラスのイベントについてファイル記述子を監視しない場合、3つのファイル記述子セットのそれぞれをNULLとして指定できます。

セットを操作するための4つのマクロが提供されています。

  • FD_ZERO ()はセットをクリアします。
  • FD_SET ()および
  • FD_CLR ()はそれぞれ、指定されたファイル記述子をセットに追加および削除します。
  • FD_ISSET ()は、ファイル記述子がセットの一部であるかどうかをテストします。

これは、 select ()が戻った後に便利です。

_nfds_は、3つのセットのいずれかで最も大きい番号のファイル記述子に1を加えたものです。

_timeout_は、 select ()が戻るまでの経過時間の上限です。 ゼロになる可能性があり、 select ()がすぐに戻ります。 (これはポーリングに役立ちます。)_timeout_がNULL(タイムアウトなし)の場合、 select ()は無期限にブロックできます。

_sigmask_はシグナルマスクへのポインターです( sigprocmask (2)を参照)。 NULLでない場合、 pselect ()はまず現在のシグナルマスクを_sigmask_が指すものに置き換え、次に「選択」機能を実行してから、元のシグナルマスクを復元します。

_timeout_引数の精度の違いを除いて、次の pselect ()呼び出し:

ready = pselect(nfds, &readfds, &writefds, &exceptfds, timeout, &sigmask);

以下の呼び出しを実行する_atomically_と同等です:

sigset_t origmask; sigprocmask(SIG_SETMASK, &sigmask, &origmask); ready = select(nfds, &readfds, &writefds, &exceptfds, timeout); sigprocmask(SIG_SETMASK, &origmask, NULL);
*pselect* ()が必要な理由は、シグナルまたはファイル記述子の準備が整うまで待機する場合、競合状態を防ぐためのアトミックテストが必要だからです。 (シグナルハンドラーがグローバルフラグを設定して戻るとします。 そして、このグローバルフラグのテストとそれに続く *select* ()の呼び出しは、テストの直後で呼び出しの直前に信号が到着した場合、無期限にハングする可能性があります。 対照的に、 *pselect* ()を使用すると、最初に信号をブロックし、入ってくる信号を処理してから、必要な_sigmask_を指定して *pselect* ()を呼び出し、競合を回避できます。)

タイムアウト

関係する時間構造は_ <sys/time.h> _で定義され、次のようになります

struct timeval { long tv_sec; /*seconds*/ long tv_usec; /*microseconds*/ };

and

struct timespec { long tv_sec; /*seconds*/ long tv_nsec; /*nanoseconds*/ };

(ただし、POSIX.1-2001バージョンについては以下を参照してください。) 一部のコードでは、3つすべてのセットが空、_n_ゼロ、およびNULL以外の_timeout_を使用して select ()を呼び出し、サブ秒精度でスリープするかなり移植性の高い方法として使用します。

Linuxでは、 select ()は_timeout_を変更して、スリープしていない時間を反映します。他のほとんどの実装はこれを行いません。 (POSIX.1-2001はどちらかの動作を許可します。)これは、_timeout_を読み取るLinuxコードが他のオペレーティングシステムに移植されるときと、複数の select ()でstruct timevalを再利用するコードがLinuxに移植されるときに問題を引き起こします再初期化せずにループします。 select ()が戻った後、_timeout_が未定義であると考えてください。

返り値

成功した場合、 select ()および pselect ()は、返される3つの記述子セットに含まれるファイル記述子の数(つまり、readfds _、 writefds exceptfds_に設定されているビットの総数)を返します。興味深いことが起こる前にタイムアウトが切れた場合。 エラーの場合、-1が返され、_errno_が適切に設定されます。セットと_timeout_は未定義になるため、エラー後にそれらの内容に依存しないでください。

エラー

Tag Description
EBADF An invalid file descriptor was given in one of the sets. (Perhaps a file descriptor that was already closed, or one on which an error has occurred.)
EINTR A signal was caught.
EINVAL nfds is negative or the value contained withintimeout is invalid.
ENOMEM unable to allocate memory for internal tables.

#include <stdio.h> #include <sys/time.h> #include <sys/types.h> #include <unistd.h> int main(void) { fd_set rfds; struct timeval tv; int retval; /*Watch stdin (fd 0) to see when it has input.*/ FD_ZERO(&rfds); FD_SET(0, &rfds); /*Wait up to five seconds.*/ tv.tv_sec = 5; tv.tv_usec = 0; retval = select(1, &rfds, NULL, NULL, &tv); /*Don’t rely on the value of tv now!*/ if (retval == -1) perror("select()"); else if (retval) printf("Data is available now.\n"); /*FD_ISSET(0, &rfds) will be true.*/ else printf("No data within five seconds.\n"); return 0; }

準拠

*select* ()はPOSIX.1-2001および4.4BSDに準拠
*pselect* ()はPOSIX.1gおよびPOSIX.1-2001で定義されています。

[[File:]] image :http://www.finddevguides.com/images/next.gif [next] [[File:]]

広告

|  

[cols="^",]

|Advertisements