同步请求
while(...) {
msg = prepare_msg(...);
send(msg, ip);
res = recv(...);
process_res(res);
}
很明显,这样做效率低
异步请求
func callback(res) {
process_res(res);
}
while(...) {
msg = prepare_msg(...);
send_async(msg, ip, callback);
}
这样就能发送异步请求,在请求返回时通过回调函数处理请求
异步请求池原理
上面唯一的问题是,我们的程序怎么知道请求返回了呢?
答案是通过epoll
发送请求后,把fd加入到epoll中,并把回调函数和epoll的事件绑定(event.data.ptr)
在另一个线程中调用epoll_wait专门处理请求的结果即可
实现
接口 (4个要素)
int dns_async_context_init(struct async_context *ctx);
int dns_async_send(struct async_context *ctx, char *msg, async_result_cb cb);
int dns_async_context_destroy();
void *dns_async_response_thread(void *arg);
数据结构
很简单,只有epfd和工作线程id
struct async_context {
int epfd;
pthread_t thid;
};
函数定义
首先是负责响应response的工作线程
void *dns_async_response_thread(void *arg) {
/*
* while (1) {
* epoll_wait();
* recv();
* parse();
* fd --> epoll delete
* }
*/
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