高级IO之简单的select_poll_epoll实验(五)

1. 题目

笔者出题:分别使用select, poll, epoll实现回显程序

2. 代码展示

2.1:select
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <err.h>
#include <unistd.h>
#include <sys/select.h>
#define MAX 20


void set_fl(int fd, int flags)
{
        int val;
        if ((val = fcntl(fd, F_GETFL, 0)) < 0)
                errx(1,"fcntl F_GETFL error");
        val |= flags;
        if (fcntl(fd, F_SETFL, val) < 0)
                errx(1,"fcntl F_SETFL error");
}

int main(void)
{
        int n;
        char buf[MAX];
        fd_set r_set;
        FD_ZERO(&r_set);
        FD_SET(STDIN_FILENO,&r_set);
        set_fl(STDIN_FILENO, O_NONBLOCK);
        set_fl(STDOUT_FILENO, O_NONBLOCK);
        while(select(1,&r_set,NULL,NULL,NULL) != -1) 
                if(fgets(buf,MAX,stdin) != NULL)
                {    
                        if(fputs(buf,stdout) == EOF)
                                errx(1,"error in write\n");
                        //FD_SET(STDIN_FILENO,&r_set); 这里要不要这句都可以,因为如果select返回必然,r_set中STDIN_FILENO置位,下次调用select的时候也不会有任何问题。
                }   
                else
                        errx(1,"end of file\n");
        exit(0);
}

结果如下:

[root@localhost ~]# ./14_2
aaa
aaa
ssss
ssss
14_2: end of file//键入crtl+d

[root@localhost ~]# 

首先fgetsfputs函数此时为非阻塞,因为这里很明显只设置了一个fd,所以select函数返回值不为-1时,直接调用fgets读取。结果显示很好的完成了任务,要重申下**select此时为同步阻塞,fgets此时是否阻塞都不重要了!**

2.2:poll
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <err.h>
#include <unistd.h>
#include <poll.h>
#define MAX 20


void set_fl(int fd, int flags)
{
        int val;
        if ((val = fcntl(fd, F_GETFL, 0)) < 0)
                errx(1,"fcntl F_GETFL error");
        val |= flags;
        if (fcntl(fd, F_SETFL, val) < 0)
                errx(1,"fcntl F_SETFL error");
}

int main(void)
{
        int n;
        char buf[MAX];
        struct pollfd fdarray;
        fdarray.fd=STDIN_FILENO;
        fdarray.events=POLLIN;
        fdarray.revents=0;
        set_fl(STDIN_FILENO, O_NONBLOCK);
        set_fl(STDOUT_FILENO, O_NONBLOCK);
        while(poll(&fdarray,1,-1) != -1) 
                if(fgets(buf,MAX,stdin) != NULL)
                {    
                        if(fputs(buf,stdout) == EOF)
                                errx(1,"error in write\n");
                }   
                else
                        errx(1,"end of file\n");
        exit(0);
}

结果如下:

[root@localhost ~]# ./14_3
aaa
aaa
ddddd
ddddd
14_3: end of file

[root@localhost ~]#

NOTE : 大体上和上述一样,不赘述。

2.3:epoll
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <err.h>
#include <unistd.h>
#include <sys/epoll.h>
#define MAX 20


void set_fl(int fd, int flags)
{
        int val;
        if ((val = fcntl(fd, F_GETFL, 0)) < 0)
                errx(1,"fcntl F_GETFL error");
        val |= flags;
        if (fcntl(fd, F_SETFL, val) < 0)
                errx(1,"fcntl F_SETFL error");
}

int main(void)
{
        int n;
        char buf[MAX];
        int efd,m;
        struct epoll_event even,events[2];
        even.events=EPOLLIN|EPOLLOUT;
        even.data.fd=STDIN_FILENO;
        set_fl(STDOUT_FILENO, O_NONBLOCK);
        set_fl(STDIN_FILENO, O_NONBLOCK);
        if((efd=epoll_create(2)) == -1) 
                errx(1,"error in epoll_create\n");
    
        if(epoll_ctl(efd,EPOLL_CTL_ADD,STDIN_FILENO,&even) == -1) 
                errx(1,"error in epoll_ctl\n");
        while((m=epoll_wait(efd,events,2,-1)) != -1) 
                for(int i=0;i<m;i++)
                        if(events[i].events & EPOLLIN == EPOLLIN)
                                if(events[i].data.fd == STDIN_FILENO)
                                        if(fgets(buf,MAX,stdin) != NULL)
                                        {    
                                                if(fputs(buf,stdout) == EOF)
                                                        errx(1,"error in write\n");
                                        }   
                                        else
                                                errx(1,"end of file\n");                                             
                                                                                                                     
        exit(0);                                                                                                     
}

结果如下:

[root@localhost ~]# ./14_4 
asd
asd
fssss
fssss
14_4: end of file

[root@localhost ~]# 

epoll_create参数随便设,大于0即可,虽然笔者这里只设置了一个fd,但是还是把events数组设置成2,目的是为了epoll_wait之后体现下由编程人员进行轮询查询的特点。结果也是很好的完成了任务 。_

3. 总结

无论使用哪个函数,其都是同步模型。也就是说编程者还必须对结果进行一定的处理。**换种说法:同步的含义代表我们效果上还是阻塞在read或者write操作上。如果将read或者write的操作投入队列中,那就是异步的方式完成了IO操作。但是不代表整体代码模型使用的是异步模型,有点绕。**而函数自身是否阻塞,也许在某些要求实时性的场合,可以改善程序效率。笔者在最后epoll刻意体现了其使用大体框架。这些函数真正的用武之地当然不是为了回显程序这么简单的要求,等笔者学到socket之后再仔细考虑这些内容吧。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值