2

我正在编写一个应用程序,它必须能够处理对它的许多并发访问,无论是通过线程还是通过进程。因此,不应对此应用互斥锁或锁。

为了使锁的使用降到最低,我将文件设计为“仅附加”,因此所有数据首先附加到磁盘,然后指向它已更新的信息的地址被更改指新的。所以我只需要实现一个小锁系统来更改这个 int 以便它引用新地址。最好的方法是什么?

我在考虑可能在地址前放置一个标志,当它被设置时,读者将使用自旋锁直到它被释放。但我担心它根本不是原子的,是吗?例如

  • 阅读器读取标志,并且未设置
  • 同时,写入者写入标志并更改 int 的值
  • 读者可能会读到不一致的值!

我正在寻找锁定技术,但我发现的只是线程锁定技术,或者锁定整个文件,而不是字段。难道不能这样做吗?仅附加数据库如何处理这个问题?

编辑:我正在研究仅附加数据库(couchDB)是如何做到的,似乎他们只使用一个线程来序列化对文件的写入。这是否意味着如果不使用文件系统锁锁定整个文件,就不可能像 sqlite 一样使它们可嵌入?

谢谢!考埃

4

2 回答 2

1

当我需要做这样的事情时,通常我会编写一个进程来接受来自其他进程的多个连接来获取数据。此日志记录过程可以维护一个文件指针,它正在将所有数据写入其中,而不会冒多次写入到同一个地方的风险。

日志进程中的每个线程只会监听新的输入并将其提交到队列中,而不会阻塞生成数据的进程。尝试在生成要记录的数据的线程中执行此操作(写入磁盘)最终会使您处于必须进行锁定操作并遭受它们所需的任何性能影响的位置。

于 2010-05-17T01:18:33.383 回答
1

请注意文件系统的附加语义——它可能不提供原子附加操作。

一种选择是将内存映射(mmap)您的文件作为共享文件,然后在指针上执行诸如比较和交换之类的原子内存操作。你的成功将取决于你的操作系统是否有这样的操作(Linux、OSX 都有)。

一个正确的(虽然我不确定它是否很快)的方式来完成你想要的rename- 它是大多数文件系统上的原子文件操作。将最新数据保存在官方文件位置。要更新数据,请将新数据写入临时文件,然后将该临时文件重命名为官方位置。

于 2010-05-17T02:20:08.667 回答