统一申请一部分请求将请求从同步变成异步
比如业务上需要DNS请求、mysql请求、redis请求等等,可以将这些请求统一进行管理和将同步变为异步。
异步请求池怎么实现epoll管理IO响应的回调函数使用线程 异步请求池的API
commitinitdestroycallback
struct epoll_arg{//epoll参数async_result_cb cb;int fd;};struct async_context{int epfd;pthread_t thid;};
init 创建epoll创建线程并传入请求的回调函数int dns_async_context_init(struct async_context *ctx){if(ctx == NULL)return -1;int epfd = epoll_create(1);if(epfd<0)return NULL;ctx->epfd = epfd;int ret = pthread_create(&ctx->epfd, NULL, dns_async_callback, ctx);//将ctx作为参数传给回调函数//在回调函数中,从参数获得对应epfd,然后再进行epoll_waitif(ret<0){return NULL;close(epfd);}return 0;}
commit 先进行DNS请求再将请求的fd放入epfdint dns_async_client_commit(struct async_context *ctx, async_result_cb cb){int sockfd = socket(AF_INET, SOCK_DGRAM, 0);if (sockfd < 0) {perror("create socket failedn");exit(-1);}printf("url:%sn", domain);struct sockaddr_in dest;bzero(&dest, sizeof(dest));dest.sin_family = AF_INET;dest.sin_port = htons(53);dest.sin_addr.s_addr = inet_addr(DNS_SVR);int ret = connect(sockfd, (struct sockaddr*)&dest, sizeof(dest));printf("connect :%dn", ret);struct dns_header header = {0};dns_create_header(&header);struct dns_question question = {0};dns_create_question(&question, domain);char request[1024] = {0};int req_len = dns_build_request(&header, &question, request);int slen = sendto(sockfd, request, req_len, 0, (struct sockaddr*)&dest, sizeof(struct sockaddr));struct epoll_arg *eparg = (struct epoll_arg*)calloc(1, sizeof(struct epoll_arg));if(eparg==NULL)return -1;eparg->fd = sockfd;eparg->cb = cb;struct epoll_event ev;ev.events = EPOLLIN;ev.data.ptr = eparg; epoll_ctl(ctx->epfd, EPOLL_CTL_ADD, sockfd, &ev);//请求之后加入epoll就退出return 0;}
callback 线程获取arg参数并进行epoll_wait等到了有事件发生就进行处理并将其从epfd中移除出来最后释放DNS资源void *dns_async_callback(void *arg){struct async_context *ctx = (struct async_context*)arg;while(1){struct epoll_event events[ASYNC_CLIENT_NUM] = {0};int nready = epoll_wait(ctx->epfd, events, ASYNC_CLIENT_NUM, -1);if(nready<0) continue;int i = 0;for(i=0; i
释放epoll、线程资源 总结
异步请求池如何提升效率?
异步请求池在io上并非是异步,而是一个请求完成之后将这个请求放入epoll,不进行等待对方响应就进行下一个下一个请求。异步的实现最主要是使用线程实现。主线程请求,回调线程处理数据,将请求与处理响应分开,而不是请求完等待响应再请求下一个,提升了效率。异步请求池和协程的区别?
首先说协程是如何实现异步的,协程是保留了各个协程和调度器切换前的工作环境,当切换时再切换回去。而异步请求池是使用线程来实现异步。请求之后交由其他线程去响应。而协程是全部过程都在同一个线程。