我正在使用boost.asio编写性能关键的双向流服务器 服务器以这种方式工作:
多个客户端同时运行,每个客户端都有自己的连接套接字,每个客户端必须同时执行两项操作:
此外,性能和多核可扩展性在此应用程序中至关重要。
标准异步方法在这里失败(发送回调可能在等待新对象发送时阻止其他回调)和阻塞方法(每个方向使用1个线程)很复杂,我无法弄清楚该做什么如果其中一个线程发生错误。
我应该为每个客户端使用2个套接字(一个用于输出,一个用于输入)?或者可能以某种方式在每个套接字上使用两个io_services,在两个不同的线程上进行并发回调支持?
请解释我如何处理这种情况。 谢谢。
答案 0 :(得分:5)
此处标准异步方法失败(发送回调可能会阻止 等待新对象发送时的其他回调)
异步模型应该可以正常工作,如果正确使用肯定会更好地扩展 - 它只会在你引入阻塞时崩溃。而不是抛弃异步,这是我的建议:
删除条件变量。您需要两个队列:OUTPUT和WAITING。
然后在处理客户时:
不需要在前一个I / O的处理程序中执行下一个I / O.这里不是阻塞条件变量,而是将其移到WAITING队列上以便以后处理。
在OUTPUT推送代码中:
这是一些伪代码:
queue<packet> output;
queue<client> waiting;
void try_send(client c)
{
if(!output.empty())
{
// there is output waiting to be sent, send it.
packet p = output.pop();
c.async_send(p, on_send_finished);
}
else
{
// nothing available, go back to waiting.
waiting.push(c);
}
}
void on_send_finished(client c)
{
// send finished, try again if any more output has accumulated:
try_send(c);
}
void push_output(packet p)
{
output.push(p);
if(!waiting.empty())
{
// there is a client waiting to send, give it a try.
client c = waiting.pop();
try_send(c);
}
}
这可以使用单个线程以可扩展的方式完成,但使用asio可以轻松实现多个线程。如果您要使用多个线程,则需要在检查队列的逻辑中引入锁定。