selectpollpipe등에 대해서 block하면서 event(읽을 수 있게 되는 상태)를 기다리기 위해서 많이 쓴다.

man page를 보면...

       select()  and pselect() allow a program to monitor multiple file descriptors, waiting until
       one or more of the file descriptors become "ready" for some class of I/O  operation  (e.g.,
       input  possible).   A  file descriptor is considered ready if it is possible to perform the
       corresponding I/O operation (e.g., read(2)) without blocking.

그렇지만 자칫 오해하면, 일반 파일에 대해서 새로 추가된 내용이 있는지 검사하고 새로 추가된 내용을 읽어들이기 위해서 selectpoll을 사용할 수 있을 거라고 기대할 수도 있다.

그렇지만, select/poll은 man page에 언급한 바처럼, "IO가 block되지 않고 IO를 행할 수 있는 상태"를 기다린다.

file descriptorread() operation을 통해서 EOF에 도달하더라도, read() operation은 blocking없이 계속해서 수행가능하다는 점 - 비록 계속 0 byte를 읽겠지만... - 을 생각해보면, 위와 같은 생각은 적합하지 않다는 것을 알 수 있다.

주의하자!


아래는 간단한 test code이다. 1초마다 계속해서 read() 가 정상 수행됨을 알 수 있다.

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <error.h>
#include <errno.h>

int
main(int argc, const char *argv[]) {
	char buf[4096];
	fd_set rfds;
	struct timeval tv;
	int fd, rb, retval;

	if (-1 == (fd = open("tstf", O_RDONLY)))
		perror("open tstf");

	/* Wait up to five seconds. */
	tv.tv_sec = 60;
	tv.tv_usec = 0;

	while (1) {
		/* Watch stdin (fd 0) to see when it has input. */
		FD_ZERO(&rfds);
		FD_SET(fd, &rfds);

		retval = select(fd + 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");
			memset(buf, 0, sizeof(buf));
			if (-1 == (rb = read(fd, buf, sizeof(buf) - 1)))
				fprintf(stderr, "%s", strerror(errno));
			printf("%s", buf);
			if (rb < (sizeof(buf) - 1))
				printf("\n---------------------------\nReaches to EOF\n");

			/* FD_ISSET(0, &rfds) will be true. */
		} else
			printf("No data within 1 minutes.\n");
		sleep(1);
	}
	exit(EXIT_SUCCESS);
}

DONE.

+ Recent posts