我该在我的应用程序中使用进程还是线程?

3

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

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

另一个任务是读取这些值并制作一个JSON对象,然后HTTP POST到特定服务器。

网络操作可能比串行慢,特别是在低GPRS覆盖范围内。

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

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

3个回答

5
在分析这个特定应用程序时,只有一个与选择pthreads相关的问题:
1.传感器读取器和网络写入器需要共享地址空间吗?
在这种情况下,我认为答案显然是“不需要”。当然这不是唯一可能的问题,但是唯一相关的问题。以下是偏好单独进程的原因:
1.应用程序的两个部分没有共同的代码; RS485与HTTP / JSON大不相同 2.责任隔离:如果RS485面板正在等待UART,则真的希望阻止HTTP面板吗? 3.让操作系统完成其工作,这样您就不必:如果使用pthread,则必须处理内核免费执行的大量同步和抢占,并且不必编写的代码将没有新错误。
进一步的分析需要比您提供的更多细节,但是以下是另一种考虑选择的方式:线程被发明来减轻进程模型的某些限制。除非您知道要达到这些限制,否则请使用单独的进程。
根据评论添加:
我同意psusi建议的设计。只需要两个进程,一个(假设为传感器读取器)仅分叉一个http发送器。两个进程可以使用像管道这样的传统IPC进行通信。传感器过程在有数据时通过管道发送数据,而子(http)进程将其打包为json并将其发送出去。
只需要两个长期运行的进程,它使用的核心数量可能与pthread实现相同,并且要正确得多。

那么你建议使用两个进程吗?这里有三个选项:1)在单个进程中使用手动线程2)在单个进程中使用 select() 3)使用两个进程。 - jacktrades
1
是的,使用 select 是一种痛苦的体验,线程也可能会是如此,但在这里并不必要。 - psusi
@jacktrades,在这种情况下,我想最简单的方法是将串口进程作为父进程...读取串口并获取样本后,使用fork()让后台进程负责将其发送到Web服务器,而前台进程则返回读取串口。 - psusi
@jacktrades,他们不需要通信...这就是为什么没有必要使用线程的原因。 - psusi
子进程可以与父进程一样长久存在,如果您的应用程序需要,那么它们可能会永远存在。 - msw
显示剩余4条评论

1

select()更有效率,因为它避免了多线程带来的上下文切换。而线程比单独的进程更有效率,因为您可以避免复制数据(除非您设置了共享内存,但此时您可能会转向使用线程)。然而,编写非阻塞I/O(例如select())更难且不容易正确实现,并且无法享受多线程带来的多任务处理。而多进程很可能是最容易实现的方式,特别是因为您可以使用curl而不必自己编写HTTP POST半部分。


你为什么认为只能在一个进程中使用libcurl? - jacktrades
@jacktrades 我没有提到libcurl。 如果您建议他使用多线程解决方案,他可以使用libcurl。 - wingedsubmariner

0

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

如果答案是肯定的:只需使用两个进程,一个轮询计量器数据并将其写入NAND存储中的环形缓冲区,另一个从环形缓冲区读取数据并发送HTTP数据。

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


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