unix网络编程 str_cli epoll 非阻塞版本
讲了使用epoll配合阻塞io来实现str_cli,这个版本是配合非阻塞io.
可以看到采用非阻塞io以后复杂度大大提升了. 这个版本是在原书select版本基础之上修改而来,可以看出epoll又比select版本复杂了很多,每次都需要调用epoll_ctl三次,效率肯定比select还低.存在一个问题!!就是epoll_wait对于重定向的stdin,始终阻塞,不晓得什么原因,以后再研究吧!
因为不能重定向stdin所以也不能测试性能,只能说是可以工作.
/* include nonb1 */#include "../lib/unp.h"#include//epoll 非阻塞io, 采用了非阻塞io以后性能得到大幅提升,但是复杂度也飞速提升。//确保events有足够的空间,这里足够了//添加一个事件到队列中,可能会改变数组中的epoll_event数量。static uint32_t addEvents(struct epoll_event * events,uint32_t nfds,int fd,uint32_t event){ int i=0; for(i=0;i 0) { if ((nwritten = write(sockfd, tooptr, n)) < 0) { if (errno != EWOULDBLOCK) err_sys("write error to socket"); } else {#ifdef VOL2 fprintf(stderr, "%s: wrote %d bytes to socket\n", gf_time(), nwritten);#endif tooptr += nwritten; /* # just written */ if (tooptr == toiptr) { toiptr = tooptr = to; /* back to beginning of buffer */ if (stdineof) Shutdown(sockfd, SHUT_WR); /* send FIN */ } } } } events[i].events = 0; //清除处理过的事件 } if (events[i].data.fd == STDOUT_FILENO) { if ((n = friptr - froptr) > 0) { if ((nwritten = write(STDOUT_FILENO, froptr, n)) < 0) { if (errno != EWOULDBLOCK) err_sys("write error to stdout"); } else {#ifdef VOL2 fprintf(stderr, "%s: wrote %d bytes to stdout\n", gf_time(), nwritten);#endif froptr += nwritten; /* # just written */ if (froptr == friptr) froptr = friptr = fr; /* back to beginning of buffer */ } } } } }}