关于write_queue_为什么要加锁的小疑问
JustDoIt0910 opened this issue · 3 comments
JustDoIt0910 commented
您好,想请教一下,如果按照现在的实现,server端connection的response()方法和发送数据包完成处理器on_write()应该都是在同一个线程,也就是connection所属的io线程调用的吧?这个write_queue_为什么需要加锁呢,是不是考虑以后有可能在线程池中执行router_.route()?
qicosmos commented
这个response 可能在用户的启动的一个线程里去response的,和io 线程不是同一个线程,需要保证线程安全。可以参考example 里async_echo例子
JustDoIt0910 commented
懂了,感谢。另外有个想法不知道可不可行。能不能另外开一个业务线程池,在invoker::apply中判断一下mode, 是Async的话,将call和response包装成一个lambda丢到线程池里,这样是不是就不用用户负责response了:
template<ExecMode model>
static inline void apply(const Function &func,
std::weak_ptr<connection> conn, const char *data,
size_t size, std::string &result,
ExecMode &exe_model)
{
using args_tuple = typename function_traits<Function>::bare_tuple_type;
exe_model = ExecMode::sync;
msgpack_codec codec;
try
{
auto tp = codec.unpack<args_tuple>(data, size);
//pseudo-code
if(is Async mode)
{
workerThreadPool_->execute([](){
call();
response();
})
}
else
call(func, conn, result, std::move(tp));
exe_model = model;
}
catch (std::invalid_argument &e)
{
result = codec.pack_args_str(result_code::FAIL, e.what());
}
catch (const std::exception &e)
{
result = codec.pack_args_str(result_code::FAIL, e.what());
}
}
qicosmos commented
这样也有问题,比如丢到线程池里执行用户函数,这个用户函数又启动了一个线程,它其实希望是在它的线程里response,这时候框架已经response了。