Труба и выберите: пример кода не работает - PullRequest
0 голосов
/ 03 марта 2011

Я что-то упустил?

Я хочу выйти из выбора, вызвав запись в другом потоке ... Он никогда не выходит из выбора.

Код тестируется на OSX Snow.

fd_set rio, wio;

int pfd [2];

void test (int sleep_time)
{
sleep (sleep_time);

char buf[] = "1";

write(pfd[1], buf, 1);

}

int main (int argc, char * argv [])

{

char buff[80];
int ended = 0;

pipe(pfd);

FD_ZERO(&rio);
FD_ZERO(&wio);

FD_SET(pfd[1], &wio);   
FD_SET(pfd[0], &rio);

pthread_t tid; /* the thread identifier */
pthread_attr_t attr; /* set of thread attributes */
pthread_attr_init(&attr);

pthread_create(tid, NULL, test, 3);

while (!ended)
{
// Check my numbers ... they do not go over 1 ... so 2
if (select(2, &rio, &wio, NULL, 0) < 0)
    perror("select");
else
{
    if (FD_ISSET(pfd[1], &wio))
    {
        if ((read(pfd[0], &buff, 80))<0) 
               perror("read");
         ended = 1;
    }
 }

}

1 Ответ

1 голос
/ 04 марта 2011

Я полагаю, у вас есть 2 ошибки:

1 - ваш вызов select ограничивает проверку максимумом fd 2, где канал, вероятно, будет иметь большие FD, поскольку 0, 1 и 2 уже открыты для stdin, stdout, stderr. Предполагается, что FD для канала будут иметь fds 3 и 4, поэтому вам действительно нужно определить больший из 2 FD для трубы и использовать его для ограничения в выборе вместо 2.

int maxfd = pfd[1];
if( pfd[0] > maxfd ) {
    maxfd = pfd[0];
}
...

2 - После выбора возвращает, вы смотрите на FD записи wio и pipe, когда вам нужно вместо этого посмотреть, есть ли что-нибудь доступное для чтения:

        if (FD_ISSET(pfd[0], &rio)) {
...