epoll初步使用2
来源:互联网 发布:上海巨人网络工资原画 编辑:程序博客网 时间:2024/06/05 16:36
上一篇中client用的是 发送->等待->接收 模式,如果把client也改为异步,一个进程发送完所有数据,再在epoll上监听返回的数据,能否成功呢。尝试了一下,程序如下:
client_single.cc
#include <stdio.h>#include <stdlib.h>#include <strings.h>#include <string.h>#include <pthread.h>#include <stdlib.h>#include <sys/epoll.h>#include <sys/stat.h>#include <sys/socket.h>#include <sys/time.h>#include <netinet/in.h>#include <arpa/inet.h>#include <sys/types.h>#include <fcntl.h>#include <unistd.h>#define BUFSIZE 10#define SENDTIME 10000#define MAXEVENTS (SENDTIME+100)pthread_attr_t attr;void setnonblocking(int sock){ int opts; opts=fcntl(sock,F_GETFL); if(opts<0) { perror("fcntl(sock,GETFL)"); exit(1); } opts = opts|O_NONBLOCK; if(fcntl(sock,F_SETFL,opts)<0) { perror("fcntl(sock,SETFL,opts)"); exit(1); }}void worker(){ char *local_addr="127.0.0.1"; int port=9988; struct epoll_event ev, events[MAXEVENTS]; int epollfd = epoll_create(1024); if(epollfd == -1){ perror("epoll_create"); exit(0); } char buf[BUFSIZE]; for(int i=0; i<SENDTIME; i++){ struct sockaddr_in serveraddr; int fd = socket(AF_INET, SOCK_STREAM, 0); if(fd == -1){ perror("socket"); exit(0); } bzero(&serveraddr, sizeof(serveraddr)); serveraddr.sin_family = AF_INET; inet_aton(local_addr,&(serveraddr.sin_addr)); serveraddr.sin_port=htons(port); int ret = connect(fd, (sockaddr*)&serveraddr, sizeof(serveraddr)); if(ret<0){ perror("connect"); exit(0); } setnonblocking(fd); int len = snprintf(buf, BUFSIZE, "%d", i); ret = write(fd, buf, len);// printf("send %s\n", buf); if(ret != len){ printf("write error %s write_len:%d expect_len:%d\n", buf, ret, len); perror(NULL); exit(0); } ev.events = EPOLLIN; ev.data.fd = fd; ret = epoll_ctl(epollfd, EPOLL_CTL_ADD, fd, &ev); if(ret == -1){ perror("epoll_ctl"); exit(0); } } int recvtime=0; while(1){ int nfds = epoll_wait(epollfd, events, MAXEVENTS, 100); if(nfds == -1){ perror(NULL); } for(int i=0; i <nfds; i++){ if(events[i].events & EPOLLIN){ int curfd = events[i].data.fd; memset(buf, 0, BUFSIZE); int n = read(curfd, buf, BUFSIZE); recvtime++; if(n<=0){ close(curfd); } else{// printf("recv %s\n", buf); close(curfd); } } } if(recvtime==SENDTIME){ break; } }} int costms(timeval *v1, timeval *v2){ if(v2->tv_usec < v1->tv_usec){ v2->tv_sec--; v2->tv_usec+=1000000; } return (v2->tv_sec - v1->tv_sec)*1000+(v2->tv_usec - v1->tv_usec)/1000;}void test(){ worker();} int main(){ timeval v1,v2; gettimeofday(&v1,NULL); test(); gettimeofday(&v2,NULL); int cost = costms(&v1, &v2); printf("cost:%dms\n", cost);}
测试发现,当上一篇中的多线程同步发送客户端为单线程时,速度慢于这里的client_single,符合预期。 但当线程数为10或更多时,发送接收同样总个数的请求,多线程同步的程序速度快于 这里的单进程异步。
而且这里的单进程异步存在一个问题:
因为一个fd发送完数据后,要将其放入epoll监听,等接收到返回数据后再关闭fd。这就导致有大量的fd为打开状态,很容易达到系统最大的fd个数,不能再创建新的fd。
所以我的想法是,对于客户端,适合用多线程的同步模式发送接收数据。仅仅是在单一场景下的想法,欢迎大家讨论。
0 0
- epoll初步使用2
- epoll初步使用
- netty初步使用2
- Git使用初步2
- epoll使用
- epoll使用
- epoll 使用
- epoll使用
- epoll使用
- epoll使用
- epoll使用
- epoll 使用
- epoll使用
- epoll使用
- epoll使用
- epoll 使用
- epoll使用
- epoll使用
- cppTest-4.0:结构体
- ConcurrentHashMap原理解析
- 异步消息的传递-回调机制
- MySql命名与设计规范
- IOS 开发随笔
- epoll初步使用2
- cppTest-4.7:枚举
- 用户追踪之基础技术——Cookie
- mnesia用户手册的阅读总结
- 解决ntp的错误 no server suitable for synchronization found
- flex socket.writeObject()发送对象,java接收flex socket发送过来的对象
- win7 64编译32位nginx-rtmp
- MapReduce:详解Shuffle过程
- mysql的性能配置 -innodb