Chinaunix

标题: 标准输入描述符是0,造成select识别异常 [打印本页]

作者: againyuan    时间: 2009-01-19 15:57
标题: 标准输入描述符是0,造成select识别异常
写了一个select的测试程序,以标准输入作为测试,出现了一个问题。
在运行 select的时候,程序中采用循环设置FD_ZERO,清空readfds.
敲入回车键,FD_ISSET检测到标准输入有数据。但是在下一次循环中不敲入回车还是被告知标准输入有数据。
这个问题是否是由于标准输入,描述符是0造成的呢?

一下程序可以运行。

#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>


int main(int argc, char *argv[])
{
        struct timeval tv;
        fd_set readfds;
        int select_rtn;
        tv.tv_sec = 2;
        tv.tv_usec = 500000;
        FD_ZERO(&readfds);
        //   将所有的文件描述符加入
        FD_SET(0, &readfds);
        /* don't care about writefds and exceptfds: */
        while(1)
        {
                tv.tv_sec = 2;
                tv.tv_usec = 500000;
                FD_ZERO(&readfds);
                FD_SET(0, &readfds);
                select_rtn = select(0+1, &readfds, NULL, NULL, NULL);
                //sleep(1);
                printf("select_rtn %d\n", select_rtn);
                if (select_rtn == -1)
                {
                        printf("将退出,select出错! %s", strerror(errno));
                        break;
                } else if (select_rtn == 0)
                {
                        printf ("没有任何消息到来,用户也没有按键,继续等待……\n");
                        continue;
                }
                else
                {
                        if (FD_ISSET(0, &readfds))
                                printf("A key was pressed!\n");
                        else
                                printf("Timed out.\n");
                }
                sleep(1);
        }
        return 0;
}
作者: scutan    时间: 2009-01-19 16:17
if (FD_ISSET(0, &readfds))
                                printf("A key was pressed!\n");

改成
if (FD_ISSET(0, &readfds))
  {
                                read(0, &ch ,1);
                                printf("A key was pressed!\n");
  }
要把那个回车给读取了。 不然一直在缓存中。
作者: againyuan    时间: 2009-01-19 16:32
多谢LZ指点,原来 select是通过对缓冲区的读取判断有无数据,然后通知应用程序的。
作者: scutan    时间: 2009-01-19 16:33
原帖由 againyuan 于 2009-1-19 16:32 发表
多谢LZ指点,原来 select是通过对缓冲区的读取判断有无数据,然后通知应用程序的。


嗯。是的,用这种方式就可以监听多个描述符。如果是read的话,就只能监听一个描述符。




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2