前提:使用libevent http模块实现httpserver服务
在http请求回调处理函数中,我们会拿到evhttp_request *指针,如下图,
如果我们直接在该回调函数中调用 evhttp_send_reply(req,...)来回复请求,则不会有我本次所说的问题,但是往往我们的业务逻辑不会如此简单(在程序设计上也不推荐回调函数中处理业务逻辑占用loop线程过多时间),而会用其他线程处理本次请求的数据(如图中所示代码,将请求封装后丢入工作队列供其他线程使用),最后再返回该线程回复req请求。
首先,evhttp_request 对象并不是线程安全的,即使你在使用libevent的时已经调用过类似于evthread_use_thread()的方法也没用,因此,evhttp_request的操作必须在event_base工作线程(即回调函数执行的线程)中进行,那么该如何在所有业务逻辑处理完后,能够在event_base线程中调用evhttp_send_reply(req...)回复请求呢?
首先,我们需要借助socket pair,然后将其中一个套接字捆绑到自定义事件event中并设置好回调函数(该回调函数会在event_base工作线程中执行自定义集合中的Function),再调用event_base_set(m_evbase, m_event);将该event绑定到我们之前创建httpserver的event_base上;
以上的准备工作做好后,当我们想要操作evhttp_request时,可以将其丢入自定义集合中再通过socket_pair的另一个套接字通知即可。