免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 7042 | 回复: 1

select和pipe的一个新的认识 [复制链接]

论坛徽章:
0
发表于 2010-07-19 00:06 |显示全部楼层
本帖最后由 kgn28 于 2010-07-19 00:08 编辑

先看程序:
  1. #include<iostream>
  2. using namespace std ;

  3. #include <fcntl.h>
  4. #include<unistd.h>
  5. #include<stdlib.h>
  6. #include<sys/types.h>
  7. #include<sys/wait.h>

  8. int inline my_sleep(int times){
  9.         struct timeval t;
  10.         t.tv_sec = times / 1000;
  11.         t.tv_usec = (times % 1000) * 1000;
  12.         select(0, NULL, NULL, NULL, &t);
  13. }

  14. int  main(int argc, char * argv)
  15. {
  16.         int n, fd[2];
  17.         pid_t p;
  18.         char buf[2048];
  19.         int maxfds;
  20.         struct timeval timeout;
  21.         int select_ret;

  22.         if(pipe(fd) < 0){
  23.                 perror("pipe create error");
  24.                 exit(2);
  25.         }

  26.         if((p = fork()) < 0){
  27.                 perror("fork error");
  28.         }else if( p  == 0) {
  29.                 close(fd[0]);
  30.                 cout<<"hi, I am the child process"<<endl;
  31.                 close(1);
  32.                 if(dup2(fd[1],1) < 0){
  33.                         perror("dup2 error");
  34.                         exit(1);
  35.                 }

  36.                 int ret = system("./scipt.sh ");

  37.                 if(ret < 0 ) {
  38.                         perror("system() error!\n");
  39.                 }else{
  40.                         if(ret == 127){
  41.                                 cout<<"Startup shell script error"<<endl;
  42.                         }else if(ret == 0){
  43.                                 cout<<"success!"<<endl;
  44.                         }else{
  45.                                 cout<<"Executing command error!"<<endl;
  46.                         }
  47.                 }
  48.                 sleep(200);
  49. //                while(1);
  50.                 exit(1);
  51.         }else{
  52.                 cout<<"Hi, i am the parent process"<<endl;
  53.                 close(fd[1]); //close write fd
  54.                 fd_set readfds;
  55.                 FD_ZERO(&readfds);
  56.                 FD_SET(fd[0],&readfds);
  57.                 maxfds = fd[0]+1;
  58.                 timeout.tv_sec =2 ;
  59.                 timeout.tv_usec = 0;
  60.                 while(true){
  61.                         select_ret = select(maxfds,&readfds,NULL,NULL,&timeout);
  62.                         if(select_ret > 0){
  63.                                 int len;
  64.                                 printf("select_ret is %d\n", select_ret);
  65.                                 if(FD_ISSET(fd[0], &readfds)){
  66.                                         len = read(fd[0],buf,2048);
  67.                                         buf[len] = '\0';
  68.                                         printf("the message recv form child pross is :%s# len=%d\n",buf, len);
  69.                                         memset(buf, 0x0, 2048);
  70.                                 }
  71.                         } else {
  72.                                 printf("select timeout\n");
  73.                         }
  74.                         timeout.tv_sec =2 ;
  75.                         timeout.tv_usec = 0;
  76.                 }
  77.                 wait(NULL);
  78.                 return 0;
  79.         }
  80. }
复制代码
起初,子进程在printf后马上退出(exit),然后产生的情况就是父进程这么select会很快的返回,并且read的返回值也是0. 加了sleep之后父进程的select都是timeout。这个现象说明:

1,重新考察select的功能,select测试的是文件描述符是否(可读、可写、例外),如果对一个文件描述符的read不会被block,那么在测试该描述符可读时,select马上返回。

2,pipe,如果子进程把write的文件描述符关闭,那么父进程read的时候不会被block并且会一直返回0以示write端已经被关闭,所以这是去select,肯定是马上返回,read的返回值也就是0了。

论坛徽章:
1
技术图书徽章
日期:2013-11-12 10:33:00
发表于 2013-08-14 20:11 |显示全部楼层
今天也遇到类似的问题,如果是命名管道的话,可以通过以O_RDWR open读端的方式来解决

原文:http://www.myvoipapp.com/blogs/y ... ifo%E4%B8%8Eselect/
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP