平台和交叉

我正在编写一个应用程序,它必须能够处理对它的许多并发访问,不管是按线程还是按进程。 所以没有互斥锁或锁应该应用于此。

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

我在考虑在地址前加上一个标志,当它被设置时,读者将使用旋转锁直到它被释放。 但是,恐怕它根本不是原子,是吗? 例如

  • 读者读取标志,并且未设置
  • 在同一时间,作家写入标志并更改int的值
  • 读者可能会读到不一致的值!
  • 我正在寻找锁定技术,但是我发现所有的技术都是用于线程锁定技术,或者锁定整个文件,而不是字段。 这是不可能的吗? 附加数据库如何处理这个问题?

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

    谢谢! Cauê


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

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

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


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

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

    链接地址: http://www.djcxy.com/p/19753.html

    上一篇: platform and cross

    下一篇: Are there equivalents to pread on different platforms?