我有一个运行 Linux 2.6 内核的 ARM 设备,总内存为 64 MB RAM。
有一个数据源,它由一个仪表组成,由 Linux 盒子通过 RS485 和 ModBus 作为应用协议进行查询。
还有另一个任务,包括读取这些值并创建一个 json 对象,然后将 HTTP POST 发送到特定服务器。
网络操作可能比串行操作慢,尤其是在 GPRS 覆盖率低的情况下。
我需要并发,程序是用 C 编写的。
你会用哪种方式并发?使用 select() 还是使用 pthreads?
我有一个运行 Linux 2.6 内核的 ARM 设备,总内存为 64 MB RAM。
有一个数据源,它由一个仪表组成,由 Linux 盒子通过 RS485 和 ModBus 作为应用协议进行查询。
还有另一个任务,包括读取这些值并创建一个 json 对象,然后将 HTTP POST 发送到特定服务器。
网络操作可能比串行操作慢,尤其是在 GPRS 覆盖率低的情况下。
我需要并发,程序是用 C 编写的。
你会用哪种方式并发?使用 select() 还是使用 pthreads?
在分析这个特定的应用程序时,实际上只有一个与选择 pthread 相关的问题:
在这种情况下,我认为答案显然是“不”。当然,这不是唯一可能的问题,而是唯一相关的问题。有理由更喜欢单独的进程:
进一步的分析需要比您给出的更多细节,但这里有另一种考虑选择的方法:发明线程是为了减轻进程模型的一些限制。除非您知道自己会遇到这些限制,否则请使用单独的流程。
为回应评论添加:
我有一半同意 psusi 的建议设计。只需要两个进程,一个(假设是传感器读取器,这是一个不错的选择)分叉一个且只有一个 http 发送者。这两个进程可以像管道一样使用传统的 IPC 进行通信。传感器进程在有一些数据时将数据发送到管道中,而子 (http) 进程将其打包成 json 并在途中发送。
它只需要两个长期存在的进程,它使用的内核数量可能与 pthread 实现的数量大致相同,而且要正确得多,要容易得多。
select() 效率更高,因为它避免了多线程带来的上下文切换。并且线程将比单独的进程更有效,因为您避免复制数据(除非您设置共享内存,但此时您可能已经使用线程)。然而,编写非阻塞 I/O,如 select(),更难做和正确,并且不喜欢多线程带来的多任务处理。并且多进程可能是最简单的实现,尤其是因为您可以使用 curl 而不是自己编写 HTTP POST 的一半。
为什么需要并发?是否必须在严格的时间间隔内轮询电表?
如果答案是 YES:只需使用两个进程,一个轮询仪表数据并写入 nand 存储中的环形缓冲区,另一个从环形缓冲区读取数据并发送 HTTP 数据。
如果答案是否定的:你根本不需要并发和非阻塞。在 main() 中使用一个大循环就足够了。