【问题标题】:Server Architecture for Embedded Device嵌入式设备的服务器架构
【发布时间】:2011-01-14 00:08:43
【问题描述】:

我正在为嵌入式 ARM 平台开发服务器应用程序。 ARM 板连接到系统将持续轮询的各种数字 IO、ADC 等。它目前正在运行一个 Linux 内核,其硬件接口被开发为驱动程序。这个想法是有一个客户端应用程序,它可以连接到嵌入式设备并在更新时接收感知数据并向设备发出命令(关闭传感器 1、重新启动传感器 2 等)。假设对感官设备的访问是通过典型的 ioctl 完成的。

现在我的问题与在嵌入式设备上运行的服务器应用程序的设计/架构有关。起初我想使用像libeventlibev 这样的轻量级C 事件处理库。应用程序将优先考虑传感器轮询事件(然后在轮询完成后将信息发送给客户端)并在收到客户端命令时处理它们(通过典型的 TCP 套接字)。服务器通常只有一个连接,但最多可能有十几个,但不会有数千个连接。这是设计这样的东西的最佳方法吗?在我列出的两个事件处理库中,哪个更适合嵌入式应用程序,还是有其他替代方案?

正在考虑的另一种方法是多线程应用程序,其中传感器轮询在读取传感数据的优先/阻塞线程中完成,每个客户端连接在单独的线程中处理。感官数据被更新为某种缓冲区/数据结构,连接线程处理将数据发送到客户端并处理客户端命令(我想你仍然需要在这些线程中使用一个事件循环来监视传入的命令) .是否使用了任何库或典型的包来帮助设计这样的应用程序,或者这是您必须从头开始的东西?

您将如何设计我想要完成的任务?

【问题讨论】:

    标签: c linux embedded client-server arm


    【解决方案1】:

    我的建议是您的第二个提案的修改形式。我会创建一个有两个线程的服务器。一个线程轮询传感器,另一个用于所有客户端连接。我在嵌入式设备 (MIPS) boost::asio 库中使用过,效果很好。

    异步处理所有套接字连接的单个线程通常可以轻松处理负载(当然,这取决于您拥有多少客户端)。然后它将提供它在共享缓冲区上的数据。为了减少互斥体的数量和复杂性,我将创建两个缓冲区,一个“活动”和另一个“非活动”,以及一个指示当前活动缓冲区的标志。轮询线程将读取数据并将其放入非活动缓冲区。当它完成并创建一个“一致”状态时,它将翻转标志并交换活动和非活动缓冲区。这可以原子完成,因此不需要比这更复杂的任何东西。

    这一切都非常易于设置,因为您几乎只有两个线程,彼此一无所知。

    【讨论】:

    • 我认为这是我要采取的方法。 C 中有没有类似于 boost::asio 的东西?
    • 我不知道这样的事情,但我使用 POSIX 的 aio_read 和朋友做了一些异步 IO。我想你可以用 aoi.h 和 poll/select 来做到这一点。
    【解决方案2】:

    我会使用 unix 域套接字——并自己编写库,因为应用程序与 linux 相关联,所以看不到使用 libvent 的任何优势,而且 libevent 也适用于数百个连接。你可以在你的守护进程中用一个线程来做你想做的所有事情。亲吻。

    您不需要专门的主线程来处理优先级队列,您只需要编写线程,以便它始终在处理其他任何事情之前处理高优先级事件。

    就库而言,您可能会受益于Google's protocol buffers(用于序列化和表示您的协议)——但它仅对 C++ 具有一流的支持,并且有线(序列化)格式有点简单位移到数字数据。我怀疑它会增加任何严重的开销。然而,另一种选择是 ASN.1 (asn1c)。

    【讨论】:

    • 协议问题也是我正在研究的问题。 Google 协议缓冲区实际上是我遇到的。还有一个仅 C 的实现也可用。 code.google.com/p/protobuf-c
    • 您必须检查 C 库的实施质量——如果 C-only 在您的优先级列表中居高不下,我会认真研究 asn.1。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-06-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-10
    • 1970-01-01
    相关资源
    最近更新 更多