要求:一个UDP服务器,在接收UDP数据包时,将收到的数据包存储到两个队列之一。工作线程与每个队列相关联,关联的线程从队列前面拾取数据包,对其进行处理并将其写入内存中缓存系统。
约束:解决方案必须基于事件循环(libuv(并用C编写
我的解决方案
-
为传入的 UDP 注册回调,将收到的数据包添加到两个队列之一并引发uv_async_send
-
为每个队列创建一个全局uv_sync_t对象,并用作uv_async_send的参数。例如:如果将数据包添加到队列 1 uv_sync_t则对象 1 用作uv_async_send的参数。同样,如果将数据包添加到队列 2,则使用对象 2 uv_sync_t
-
启动两个线程,每个线程都有自己的循环和一个绑定回调的句柄
- 在线程一中uv_sync_t对象 1 绑定到一个函数(比如 funcA(。在线程二中uv_sync_t对象 2 绑定到另一个函数(例如 funcB(
- funcA 和 funcB 从相应的队列中读取"SINGLE"数据包并将其存储在内存缓存中
问题所在客户端发送大量数据包,这些数据包在服务器中注册大量事件。现在的问题是 libuv 将多个调用合并为一个并调用单个回调(这会从队列中删除单个节点(。这会导致节点以更快的速度添加到队列中,并以非常慢的速度删除的情况。这些费率可以平衡吗?
有没有更好的方法来使用事件循环库libuv设计服务器?
由于在一个线程中对数据包进行排队,但在另一个线程中处理数据包,因此它们的工作方式可能略有不同。我会使用线程安全队列(看看 concurrencykit.org(并在异步回调上处理整个队列,而不仅仅是处理单个数据包。