3

我有一个运行 Linux 2.6 内核的 ARM 设备,总内存为 64 MB RAM。

有一个数据源,它由一个仪表组成,由 Linux 盒子通过 RS485 和 ModBus 作为应用协议进行查询。

还有另一个任务,包括读取这些值并创建一个 json 对象,然后将 HTTP POST 发送到特定服务器。

网络操作可能比串行操作慢,尤其是在 GPRS 覆盖率低的情况下。

我需要并发,程序是用 C 编写的。

你会用哪种方式并发?使用 select() 还是使用 pthreads?

4

3 回答 3

5

在分析这个特定的应用程序时,实际上只有一个与选择 pthread 相关的问题:

  1. 传感器读取器和网络写入器是否需要共享地址空间?

在这种情况下,我认为答案显然是“不”。当然,这不是唯一可能的问题,而是唯一相关的问题。有理由更喜欢单独的进程:

  1. 应用程序的两半没有共同的代码;RS485 与 HTTP/JSON 大不相同
  2. 责任分离:如果 RS485 端在等待 UART,你真的要阻塞 HTTP 端吗?
  3. 让操作系统完成它的工作,这样你就不必:如果使用 pthreads,你必须处理内核免费为你做的大量同步和抢占,而你不必编写的代码没有新的错误。

进一步的分析需要比您给出的更多细节,但这里有另一种考虑选择的方法:发明线程是为了减轻进程模型的一些限制。除非您知道自己会遇到这些限制,否则请使用单独的流程。

为回应评论添加

我有一半同意 psusi 的建议设计。只需要两个进程,一个(假设是传感器读取器,这是一个不错的选择)分叉一个且只有一个 http 发送者。这两个进程可以像管道一样使用传统的 IPC 进行通信。传感器进程在有一些数据时将数据发送到管道中,而子 (http) 进程将其打包成 json 并在途中发送。

它只需要两个长期存在的进程,它使用的内核数量可能与 pthread 实现的数量大致相同,而且要正确得多,要容易得多。

于 2013-09-09T18:48:24.163 回答
1

select() 效率更高,因为它避免了多线程带来的上下文切换。并且线程将比单独的进程更有效,因为您避免复制数据(除非您设置共享内存,但此时您可能已经使用线程)。然而,编写非阻塞 I/O,如 select(),更难做和正确,并且不喜欢多线程带来的多任务处理。并且多进程可能是最简单的实现,尤其是因为您可以使用 curl 而不是自己编写 HTTP POST 的一半。

于 2013-09-10T03:11:52.670 回答
0

为什么需要并发?是否必须在严格的时间间隔内轮询电表?

如果答案是 YES:只需使用两个进程,一个轮询仪表数据并写入 nand 存储中的环形缓冲区,另一个从环形缓冲区读取数据并发送 HTTP 数据。

如果答案是否定的:你根本不需要并发和非阻塞。在 main() 中使用一个大循环就足够了。

于 2013-10-08T08:25:07.403 回答