我正在编写一个服务器守护进程,用户可以从中查询C中的数据。还可以从客户端修改数据。在内存中有数据库 - C
我想过把数据保存在内存中。
对于每一个新的连接,我做一个fork()。
我首先想到的是,这会在每次连接发生时都会生成db的副本,这是浪费内存。
我的第二个问题是我不知道如何修改父进程中的数据库。
有什么概念来解决这些问题?
我正在编写一个服务器守护进程,用户可以从中查询C中的数据。还可以从客户端修改数据。在内存中有数据库 - C
我想过把数据保存在内存中。
对于每一个新的连接,我做一个fork()。
我首先想到的是,这会在每次连接发生时都会生成db的副本,这是浪费内存。
我的第二个问题是我不知道如何修改父进程中的数据库。
有什么概念来解决这些问题?
有什么概念可以解决这些问题?
就在几个意见:
fork()
只克隆处执行执行的时间进程的内存。如果您尚未在此阶段打开或加载数据库,则不会将其克隆到子进程中。mmap()
和MAP_SHARED
的内存将在进程间共享,并且不会被复制。除了在现代的Linux系统,fork()
工具写入时复制进程内存的复制。实际上,不会在内存中结束了一个进程的两个副本 - 最终会有一个副本相信它已被复制两次。如果你写任何内存,然后它将被复制。这是一种节省效率的方式,它利用了大多数进程在运行时只改变其一小部分内存的事实,所以事实上,即使您使用整个数据库方法进行复制,您也可能会发现内存使用率较低你的期望 - 虽然当然不会解决你的同步问题!
Shared memory
and multi-threading
是在多个执行单元之间共享内存的两种方式。检查出多线程的POSIX Threads,并且别忘了在别人正在读取时使用互斥锁和/或信号来锁定内存区域的写入。
所有这些都是concurrency
较大问题的一部分。有多本关于并发性问题的书籍和整个大学课程,所以如果你发现自己迷路了,也许你需要坐下来研究一下。如果你不小心,将死锁和竞态条件引入并发C程序是非常容易的。
他们可能不应该是同一个应用程序的一部分,你可以永远让你的数据库成为一个单独的进程,并使用IPC与它进行通信,甚至使用像sqlite这样简单的东西来代替,以使其更容易对自己 –
好吧,我会有看看IPC(也许有一个很好的教程解释它?)像bind9这样的守护进程如何做到这一点?我很确定他们在内存中获得了数据库,但没有单独的数据库进程。 – Zulakis
为什么不使用线程而不是叉子?这解决了你提到的所有问题。他们通常也更快。 – usr