我正在研究嵌入式ARM平台的服务器应用程序。 ARM板连接到系统将一致轮询的各种数字IO,ADC等。它目前正在运行Linux内核,其硬件接口是作为驱动程序开发的。该想法是具有客户端应用程序,其可以连接到嵌入式设备并在更新时接收传感数据并向设备发出命令(关闭传感器1,重启传感器2等)。假设通过典型的ioctl来访问传感设备。
现在我的问题涉及在嵌入式设备上运行的此服务器应用程序的设计/体系结构。起初我想使用像libevent或libev这样的轻量级C事件处理库。应用程序将优先考虑传感器轮询事件(然后在轮询完成后将信息发送到客户端)并在接收到客户端命令时(通过典型的TCP套接字)处理客户端命令。服务器通常只有一个连接,但最多可能有十几个,但不是几千个连接。这是设计这样的东西的最佳方法吗?在我列出的两个事件处理库中,对嵌入式应用程序更好,还是有其他选择?
正在考虑的另一种方法是多线程应用程序,其中传感器轮询在优先级/阻塞线程中完成,该线程读取传感数据并且每个客户端连接在单独的线程中处理。感知数据被更新为某种缓冲区/数据结构,连接线程处理将数据发送到客户端并处理客户端命令(我猜你仍然需要在这些线程中进行排序的事件循环来监视传入的命令) 。是否有任何库或典型的软件包可以帮助设计这样的应用程序,或者这是你必须从头开始的事情?
你将如何设计我想要完成的任务?
答案 0 :(得分:3)
我会使用一个unix域套接字 - 并自己编写库,看不到使用libvent的任何优点,因为应用程序与linux绑定,而libevent也适用于数百个连接。您可以使用守护程序中的单个线程执行所有要执行的操作。 KISS。
您不需要专门的主线程来获得您只需要编写线程的优先级队列,这样它就可以先处理高优先级事件。
就库而言,您可能会受益于Google's protocol buffers(用于序列化和表示您的协议) - 但是它只对C ++有一流的支持,并且有线(序列化)格式有点简单的位移到数字数据。我怀疑它会增加任何严重的开销。然而另一种选择是ASN.1(asn1c)。
答案 1 :(得分:2)
我的建议是您第二个提案的修改后的形式。我会创建一个有两个线程的服务器。一个线程轮询传感器,另一个线程用于所有客户端连接。我已经在嵌入式设备(MIPS)boost::asio库中使用了很好的结果。
以异步方式处理所有套接字连接的单个线程通常可以轻松处理负载(当然,这取决于您拥有多少个客户端)。然后它将提供它在共享缓冲区上的数据。为了减少互斥锁的数量和复杂性,我将创建两个缓冲区,一个是“活动”而另一个是“非活动”,还有一个标志来指示当前活动缓冲区。轮询线程将读取数据并将其放入非活动缓冲区。当它完成并创建了“一致”状态时,它将翻转标志并交换活动和非活动缓冲区。这可以原子方式完成,因此不需要比这更复杂的东西。
这一切都非常设置简单,因为你几乎只有两个线程对另一个一无所知。