POSIX共享内存与C中的动态链接库/对象

POSIX共享内存与C中的动态链接库/对象,c,dll,shared-memory,dlopen,C,Dll,Shared Memory,Dlopen,我在自学C,我开始意识到我的老师不是最好的;-) 在Linux上使用GCC 我正在开发一个用于收集物联网数据的时间序列数据库,该数据库设计用于在资源有限的计算机上运行(Pi零等)。 我希望能够使用多个数据采集器为单个数据库提供数据,并且能够动态添加/删除数据采集器 最初,我编写它是为了使用dlopen()根据配置文件加载库。要更改库,我只需更新配置文件,然后向主程序发送一个SIGUSER2命令它重新加载。 到目前为止,这似乎工作正常 我决定能够与其他应用程序实时共享数据,因此在比较了不同类型的I

我在自学C,我开始意识到我的老师不是最好的;-)

在Linux上使用GCC

我正在开发一个用于收集物联网数据的时间序列数据库,该数据库设计用于在资源有限的计算机上运行(Pi零等)。
我希望能够使用多个数据采集器为单个数据库提供数据,并且能够动态添加/删除数据采集器

最初,我编写它是为了使用dlopen()根据配置文件加载库。要更改库,我只需更新配置文件,然后向主程序发送一个SIGUSER2命令它重新加载。 到目前为止,这似乎工作正常

我决定能够与其他应用程序实时共享数据,因此在比较了不同类型的IPC之后,我决定使用POSIX风格的共享内存。 如果我理解正确,即使我在共享内存中使用相对较小的结构(比如60字节),它也会分配1页(4k)的内存

假设这是正确的,我想我最好使用共享内存与数据采集器通信,并将它们作为单独的程序运行。我可以在结构内部为每个数据采集器预先分配单独的变量数组,然后让主应用程序依次向它们发送信号,以允许它们写入SHM。 除了使主应用程序代码更简单之外,这还将在某种程度上将其与数据采集器隔离开来。如果其中一个崩溃,它不会停止主应用程序。数据采集器可以随时启动和停止,而无需重新加载主应用程序。另外,由于它是共享内存,其他应用程序可以实时从采集器读取数据

问题: 我认为这将使用更少的资源,因为我不再需要使用dlopen(),这似乎正确吗

有人认为这个想法有什么重大问题吗


最重要的是,我假设任何应用程序都可以随时从共享内存中读取(假设读取是原子的),而无需对其进行协调,这是否正确

理想情况下,使用共享内存并将模块作为不同的进程来实现与根据配置文件使其最初加载共享对象的问题无关

动态模块的使用允许您在运行时加载/卸载这些模块,因此对于将在运行时加载或失效的代码片段,这是一个好主意(例如,如果您决定开始使用该IoT协议的新版本,并且您不想阻止其他人这样做)

解决了usin动态可加载模块的可能性后,让我们转到另一个问题:

如果每个模块都是单个应用程序的一部分,并且您已经正确定义了它们将使用的api,那么如何注册模块并开始使用它,并且它们共享相同的虚拟空间(相同的数据内存)最好的解决方案可能不是重复使用共享内存、队列等。最有可能的解决方案是使用多线程,让所有线程在单个进程中运行。这将自动使所有线程共享进程内存,并且线程库通常有一组不同的锁定系统来控制进程阻塞资源,以便没有线程中断其他线程正在使用的数据

一个很好的库示例是POSIX线程库(
libpthread
),它实现了所有锁机制,如互斥锁、条件变量、信号量等


要同时使用这两种功能,可以定义一个注册api以允许加载主线程(
dlopen
)一个共享的可执行文件,单独编译,并在单独的线程中开始数据采集,而其他线程在数据库的不同部分上工作。您甚至可以定义不同类型的模块,一个用于CoAP,另一个用于M2M,另一个用于opc ua,以及其他用于将所有内存数据异步转储到sql数据库中的模块,例如你可以做的事情。如果你把它组织得很好,你可以得到一个非常好的方法,在像Raspberry或更小的小型设备上运行良好。

如果你选择共享内存,你必须添加同步机制(信号量、互斥等)管理并发读/写访问。否则,共享内存缓冲区中存在数据不一致的风险。其他IPS机制可能更容易,例如消息队列。