используя select () с конвейером - PullRequest
7 голосов
/ 05 августа 2011

Я читаю / пишу в трубу, созданную pipe(pipe_fds).Итак, в основном со следующим кодом, я читаю из этого канала:

fp = fdopen(pipe_fds[0], "r"); 

И когда я что-то получаю, я распечатываю это следующим образом:

while (fgets(buf, 200, fp)) {
    printf("%s", buf);
}

То, что я хочу, это когдав течение определенного промежутка времени ничего не появляется на pipe до read с, я хочу знать об этом и сделать:

printf("dummy");

Может ли это быть достигнуто с помощью select () ?Любые указатели о том, как это сделать, будут великолепны.

Ответы [ 2 ]

11 голосов
/ 05 августа 2011

Допустим, вы хотели подождать 5 секунд, а затем, если в канал ничего не было записано, вы выводите «dummy».

fd_set set;
struct timeval timeout;

/* Initialize the file descriptor set. */
FD_ZERO(&set);
FD_SET(pipe_fds[0], &set);

/* Initialize the timeout data structure. */
timeout.tv_sec = 5;
timeout.tv_usec = 0;

/* In the interest of brevity, I'm using the constant FD_SETSIZE, but a more
   efficient implementation would use the highest fd + 1 instead. In your case
   since you only have a single fd, you can replace FD_SETSIZE with
   pipe_fds[0] + 1 thereby limiting the number of fds the system has to
   iterate over. */
int ret = select(FD_SETSIZE, &set, NULL, NULL, &timeout);

// a return value of 0 means that the time expired
// without any acitivity on the file descriptor
if (ret == 0)
{
    printf("dummy");
}
else if (ret < 0)
{
    // error occurred
}
else
{
    // there was activity on the file descripor
}
0 голосов
/ 05 августа 2011

IIRC, select имеет тайм-аут, который вы затем проверяете с помощью FD_ISSET, чтобы узнать, был ли это ввод / вывод или нет.

...