C言語システムコール-poll
pollシステムコール
概要
pollは複数のファイルディスクリプタ(ファイル記述子)を監視/制御します。
pollシステムコールを用いた処理の待ち合わせ制御を「ポーリング(polling)」といいます。
ファイルディスクリプタで処理を待ち合わせるシステムコール(readやacceptなど)を実行すると、データが到着するなどの一連の処理が完了するまでシステムコールから処理制御はリターンされません。
つまり、ファイルディスクリプタへのデータ到着を待ち合わせる場合、待ち合わせ状態のディスクリプタにデータが到着して処理が完了するまでは、他のディスクリプタに到着したデータは処理を見合わせることとなります。
そのような場合にselectシステムコールを利用することで、複数のファイルディスクリプタに対する状態変化を監視して、効率的な待ち合わせ制御を行うことが可能になります。
pollと同等の機能としてselectシステムコールがあります。
pollシステムコールはSystem V系のシステムコールであり、selectはBSD系システムコールです。
サンプルプログラム
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <poll.h>
/*!
* @brief 標準入力から標準出力へエコーする
*/
static int
echo_process(void)
{
ssize_t rnum = 0;
ssize_t wnum = 0;
char buf[BUFSIZ] = {"¥0"};
rnum = read(0, buf, sizeof(buf));
if(rnum < 0){
printf("Error: read(%d) %s\n", errno, strerror(errno));
return(-1);
}
wnum = write(1, buf, rnum);
if(wnum < 0){
printf("Error: write(%d) %s\n", errno, strerror(errno));
return(-1);
}
return(0);
}
/*!
* @brief 標準入力を待ち合わせる。
* @param[in] filepath ファイルパス名
* @return 0:success/-1:failure
*/
static int
select_stdin(void)
{
int rc = 0;
struct pollfd fds[1];
fds[0].fd = 0;
fds[0].events = POLLIN;
fds[0].revents = 0;
/* 待ち合わせ時間 : 3.5秒 */
rc = poll(fds, 1, 3500);
if(rc < 0){
printf("Error: poll() %s\n", strerror(errno));
return(-1);
}else if(rc == 0){
/* タイムアウト */
printf("CAUTION: timeout\n");
return(-1);
}
if(fds[0].revents & POLLIN){
/* 待ち合わせに到着 */
echo_process();
}
return(0);
}
int
main(int argc, char *argv[])
{
int rc = 0;
if(argc != 1){
fprintf(stderr, "Usage: %s\n", argv[0]);
exit(EXIT_FAILURE);
}
rc = select_stdin();
if(rc != 0) exit(EXIT_FAILURE);
exit(EXIT_SUCCESS);
}