嵌入式设备的服务器架构

3
我正在为嵌入式ARM平台开发服务器应用程序。 ARM板连接到各种数字IO,ADC等,系统将一直轮询它们。它目前运行的是Linux内核,硬件接口开发为驱动程序。想法是有一个客户端应用程序可以连接到嵌入式设备并在更新时接收传感器数据,并向设备发出命令(关闭传感器1,重新启动传感器2等)。假设对传感器设备的访问是通过典型的ioctl完成的。
现在我的问题涉及运行在嵌入式设备上的此服务器应用程序的设计/架构。起初,我考虑使用类似libeventlibev的轻量级C事件处理库。应用程序将优先处理传感器轮询事件(然后在轮询完成后将信息发送给客户端),并在接收到客户端命令时进行处理(通过典型的TCP套接字)。服务器通常只有一个连接,但可能最多有十几个连接,而不是像成千上万的连接那样。这是设计这样东西的最佳方法吗?在我列出的两个事件处理库中,哪一个更适合嵌入式应用程序,还是有其他替代方案?
另一个考虑中的方法是多线程应用程序,其中传感器轮询在具有优先级/阻塞线程的情况下完成,该线程读取感官数据,每个客户端连接在单独的线程中处理。感官数据被更新到某种缓冲区/数据结构中,连接线程处理将数据发送到客户端并处理客户端命令(我想您仍然需要这些线程中的某种事件循环来监视传入的命令)。是否有任何库或典型软件包可用于简化设计此类应用程序,还是必须从头开始?
你会如何设计我所要实现的内容?
2个回答

3

我会使用Unix域套接字 - 并自己编写库,因为我看不到使用libevent的任何优势,因为应用程序与Linux绑定,而且libevent也适用于数百个连接。您可以在守护进程中的单个线程中完成您要尝试的所有操作。简单易行。

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

在库方面,您可能会从Google的协议缓冲区(用于序列化和表示您的协议)中受益 - 但是它仅支持C++的一流,而且通过网络传输(序列化)格式对数字数据进行了一些简单的位移。我怀疑它不会增加任何严重的开销。但是,另一种选择是ASN.1(asn1c)。


协议问题也是我正在研究的内容。Google协议缓冲区实际上是我偶然发现的。还有一个仅限于C语言的实现版本可用。http://code.google.com/p/protobuf-c/ - mhilmi
你需要检查C库的实现质量——如果仅使用C是你的首要考虑因素,我建议认真考虑asn.1。 - Hassan Syed

2
我的建议是对你的第二个方案进行修改。我会创建一个有两个线程的服务器。一个线程用于轮询传感器,另一个用于处理所有客户端连接。我在嵌入式设备(MIPS)中使用了boost::asio库,并取得了很好的结果。
通常情况下,一个处理所有套接字连接的单线程可以轻松处理负载(当然,这取决于您有多少客户端)。然后它会在共享缓冲区上提供数据。为了减少互斥锁的数量和复杂性,我会创建两个缓冲区,一个“活动”缓冲区和另一个“非活动”缓冲区,并使用一个标志来指示当前活动的缓冲区。轮询线程将读取数据并将其放入非活动缓冲区中。当它完成并创建了一个“一致”的状态时,它会翻转标志并交换活动和非活动缓冲区。这可以原子地完成,因此不需要更复杂的东西。
由于你几乎只有两个线程,它们互相不知道,所以设置这一切都非常简单。

我认为这是我要采取的方法。在C语言中是否有类似于boost::asio的东西? - mhilmi
我不知道有类似的东西,但我使用了POSIX的aio_read和相关函数进行了一些异步IO。我猜你可以使用aoi.h和poll/select来做到这一点。 - Gianni

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接