2012-06-16 35 views
1

我正在编写一个服务器守护进程,用户可以从中查询C中的数据。还可以从客户端修改数据。在内存中有数据库 - C

我想过把数据保存在内存中。

对于每一个新的连接,我做一个fork()。

我首先想到的是,这会在每次连接发生时都会生成db的副本,这是浪费内存。

我的第二个问题是我不知道如何修改父进程中的数据库。

有什么概念来解决这些问题?

+2

他们可能不应该是同一个应用程序的一部分,你可以永远让你的数据库成为一个单独的进程,并使用IPC与它进行通信,甚至使用像sqlite这样简单的东西来代替,以使其更容易对自己 –

+0

好吧,我会有看看IPC(也许有一个很好的教程解释它?)像bind9这样的守护进程如何做到这一点?我很确定他们在内存中获得了数据库,但没有单独的数据库进程。 – Zulakis

+2

为什么不使用线程而不是叉子?这解决了你提到的所有问题。他们通常也更快。 – usr

回答

1

有什么概念可以解决这些问题?

就在几个意见:

  1. fork()只克隆处执行执行的时间进程的内存。如果您尚未在此阶段打开或加载数据库,则不会将其克隆到子进程中。
  2. Shared memory - 即映射为mmap()MAP_SHARED的内存将在进程间共享,并且不会被复制。
  3. 流程间通信的通用术语是Interprocess communication,其中有几种类型和品种,具体取决于您的需求。

除了在现代的Linux系统,fork()工具写入时复制进程内存的复制。实际上,不会在内存中结束了一个进程的两个副本 - 最终会有一个副本相信它已被复制两次。如果你写任何内存,然后它将被复制。这是一种节省效率的方式,它利用了大多数进程在运行时只改变其一小部分内存的事实,所以事实上,即使您使用整个数据库方法进行复制,您也可能会发现内存使用率较低你的期望 - 虽然当然不会解决你的同步问题!

3

Shared memory and multi-threading是在多个执行单元之间共享内存的两种方式。检查出多线程的POSIX Threads,并且别忘了在别人正在读取时使用互斥锁和/或信号来锁定内存区域的写入。

所有这些都是concurrency较大问题的一部分。有多本关于并发性问题的书籍和整个大学课程,所以如果你发现自己迷路了,也许你需要坐下来研究一下。如果你不小心,将死锁和竞态条件引入并发C程序是非常容易的。