免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12
最近访问板块 发新帖
楼主: AnkerLi
打印 上一主题 下一主题

[函数] 关于select函数的问题 [复制链接]

论坛徽章:
5
戌狗
日期:2014-06-09 10:29:10酉鸡
日期:2014-12-01 16:05:27处女座
日期:2015-01-07 18:35:262015亚冠之水原三星
日期:2015-06-03 09:26:222015亚冠之布里斯班狮吼
日期:2015-06-15 10:53:54
11 [报告]
发表于 2015-02-04 08:31 |只看该作者
回复 10# AnkerLi


    我上面说了,读到结尾之后,不走那个分支了,这个rc之后为0,不会执行printf语句
                 if(rc>0){
                     buf[rc]='\0';
                     printf("read: %s\n",buf);
                 }else
                     perror("read");

论坛徽章:
2
2015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:56:11
12 [报告]
发表于 2015-02-04 11:02 |只看该作者
读到结尾FD_ISSET都通不过,还read什么?

论坛徽章:
1
2015元宵节徽章
日期:2015-03-06 15:53:22
13 [报告]
发表于 2015-02-04 22:27 |只看该作者
本帖最后由 AnkerLi 于 2015-02-04 22:27 编辑

回复 11# kaede_1


    兄台,好像你运行的结果和我运行的结果还是有点小差异的。你运行的结果里有read: Success这句,为什么我运行的结果里并没有这一句?你所运行的程序和我的是不一样的吗?
[root@localhost select_test]# ./select_test
rc=7
read: Hello!

rc=7,write: Hello!

rc=7,write: Hello!

rc=7,write: Hello!

rc=7,write: Hello!

rc=7,write: Hello!

rc=7,write: Hello!

rc=7,write: Hello!

rc=7,write: Hello!

。。。。。。

论坛徽章:
5
戌狗
日期:2014-06-09 10:29:10酉鸡
日期:2014-12-01 16:05:27处女座
日期:2015-01-07 18:35:262015亚冠之水原三星
日期:2015-06-03 09:26:222015亚冠之布里斯班狮吼
日期:2015-06-15 10:53:54
14 [报告]
发表于 2015-02-05 11:38 |只看该作者
具体的你可以man 3 perror
这里perror函数是针对read不正常的情况,而在你的程序中,read到结尾,并没有报错,返回值为0,而0对应的strerror(errno)=Success
因此perror的打印信息就是msg:Success

论坛徽章:
1
2015元宵节徽章
日期:2015-03-06 15:53:22
15 [报告]
发表于 2015-02-05 16:46 |只看该作者
本帖最后由 AnkerLi 于 2015-02-05 16:50 编辑

回复 14# kaede_1


      不是很明白。你的意思是我的程序会打印msg:success?
      其实,我的程序在运行时,通过加了一句语句(具体如7楼所说的),发现FD_ISSET(fds[0],&inset1)这个返回值只有第一次为真,后面都为假。运行如下:
       [root@localhost select_test]# ./select_test
rc=7
read: Hello!
RRR=0

rc=7,write: Hello!

rc=7,write: Hello!

rc=7,write: Hello!

rc=7,write: Hello!

rc=7,write: Hello!

rc=7,write: Hello!

rc=7,write: Hello!

rc=7,write: Hello!

。。。。。。

论坛徽章:
5
戌狗
日期:2014-06-09 10:29:10酉鸡
日期:2014-12-01 16:05:27处女座
日期:2015-01-07 18:35:262015亚冠之水原三星
日期:2015-06-03 09:26:222015亚冠之布里斯班狮吼
日期:2015-06-15 10:53:54
16 [报告]
发表于 2015-02-09 15:23 |只看该作者

msg:Success代表perror函数读到结尾时显示的格式
你确定FD_ISSET(fds[0],&inset1)这个返回值只有第一次为真??
  1. #include <fcntl.h>
  2. #include <stdio.h>
  3. #include <unistd.h>
  4. #include <stdlib.h>
  5. #include <time.h>
  6. #include <errno.h>
  7. #include <string.h>
  8. int main(void)
  9. {
  10.     int fds[2];
  11.     char buf[7];
  12.     int i,rc,maxfd;
  13.     fd_set inset1,inset2;
  14.     struct timeval tv;
  15.     /*首先按一定的权限打开hello1文件*/
  16.     if((fds[0] = open ("hello1", O_RDWR|O_CREAT,0666))<0)
  17.         perror("open hello1");
  18.     /*再按一定的权限打开hello2文件*/
  19.     if((fds[1] = open ("hello2", O_RDWR|O_CREAT,0666))<0)
  20.         perror("open hello2");
  21.     if((rc = write(fds[0],"Hello!\n",7)))
  22.     printf("rc=%d\n",rc);
  23.     lseek(fds[0],0,SEEK_SET);
  24.     /*取出两个文件描述符中的较大者*/
  25.     maxfd = fds[0]>fds[1] ? fds[0] : fds[1];
  26.     /*初始化读集合inset1,并在读集合中加入相应的描述集*/
  27.     FD_ZERO(&inset1);
  28.     FD_SET(fds[0],&inset1);
  29.     /*初始化写集合inset2,并在写集合中加入相应的描述集*/
  30.     FD_ZERO(&inset2);
  31.     FD_SET(fds[1],&inset2);
  32.     tv.tv_sec=1;
  33.     tv.tv_usec=0;
  34.     /*循环测试该文件描述符是否准备就绪,并调用select函数对相关文件描述符做对应操作*/
  35.     while(FD_ISSET(fds[0],&inset1)||FD_ISSET(fds[1],&inset2)){
  36.          if(select(maxfd+1,&inset1,&inset2,NULL,&tv)<0)
  37.                 perror("select");
  38.          else{
  39.                if(FD_ISSET(fds[0],&inset1)){
  40.                      rc = read(fds[0],buf,7);
  41.                      if(rc>0){
  42.                          buf[rc]='\0';
  43.                          printf("read: %s\n",buf);
  44.                      }else
  45.                      {
  46.                          //errno=1;
  47.                          printf("Here:%d:%s\n",errno,strerror(errno));
  48.                          perror("read");
  49.                      }
  50.                  }
  51.                 if(FD_ISSET(fds[1],&inset2)){
  52.                       rc = write(fds[1],buf,7);
  53.                       if(rc>0){
  54.                           buf[rc]='\0';
  55.                           printf("rc=%d,write: %s\n",rc,buf);
  56.                  }else
  57.                           perror("write");
  58.                  sleep(10);
  59.                  }
  60.           }
  61.     }
  62.     return 0;
  63. }
复制代码
看看输出时Here那一段

论坛徽章:
0
17 [报告]
发表于 2015-06-01 15:03 |只看该作者
本帖最后由 luyunxm 于 2015-06-01 15:48 编辑

,AnkerLi,我明白你的意思了
我的回答:
FD_ISSET(fds[0],&inset1)因为文件没阻塞,每次都会可读而返回真,但是read函数在文件已到达文件尾时会返回0(读成功:读到字节数 0:已到达文件尾 -1:出错),所以执行else语句;
如果你想下一次还可读写必须使用lseek函数把文件指针指回来;或是使用close关闭,然后open再打开一次这个文件

而FD_ISSET(fds[1],&inset2)因为文件没阻塞,每次都可写而返回真,write函数返回已经写的字节数,所以一直执行if语句

kaede_1说得很正确

论坛徽章:
0
18 [报告]
发表于 2015-06-02 13:07 |只看该作者
while 条件有问题吧?
select之后才能用FD_ISSET吧?
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP