POSIX 兼容的文件锁定(在单个进程内)?

POSIX-compliant file locking (within a single process)?

我正在制作一个 client/server 系统,客户端可以在其中下载文件并将文件上传到服务器(一个客户端可以同时执行多个此类操作)。如果客户端崩溃,它必须在重新启动时恢复其中断的操作。

显然,我需要一些元数据文件来跟踪当前操作。每当数据块 downloaded/uploaded 时,线程就会访问它。此外,客户端应用程序应该能够以 %.

打印所有文件的 download/upload 进度

我不介意为单个条目(对应于单个 download/upload 操作)更新锁定整个元文件,但至少读取它应该允许线程并发(除非在一个文件很快)。

This 文章说进程间文件锁定在 POSIX 中很糟糕。我有哪些选择?

编辑:可能已经很清楚了,但我系统中的并发性必须基于 pthreads

This article says that inter-process file locking sucks in POSIX. What options do I have?

文章正确描述了 inter-process 文件锁定的状态。在您的情况下,您只有一个进程,因此不会发生进程间锁定。

[...] concurrency in my system must be based on pthreads.

如您所说,其中一种可能性是使用全局互斥锁来同步对元文件的访问。

最小化锁定的一种方法是使元文件中的 per-thread/per-file 条目具有可预测的大小(为了获得与文件系统块大小对齐的最佳结果)。这将允许以下内容:

  • 在保持全局互斥锁的同时,通过将 per-file/per-thread 条目附加到元文件的末尾并保存其文件偏移量来分配元文件中的条目,
  • 有了文件偏移量,使用pread()/pwrite()函数更新文件操作信息,不使用也不影响全局文件偏移量。

由于每个线程都会写入其自己的元文件区域,因此不应存在竞争条件。

(如果条目数有上限,那么也可以预分配整个文件,然后mmap()它,然后像普通内存一样使用它。如果应用程序崩溃,最最近的状态(可能有一些损坏;毕竟应用程序已经崩溃)将出现在文件中。一些应用程序在软件崩溃后加速重启,尽可能将应用程序的整个状态保持在 mmap()编辑文件。)

另一种方法是将元文件用作"journal":以追加模式打开元文件;作为入口,写入待处理文件操作的状态变化,包括文件操作的开始和结束。崩溃后,要恢复文件传输的状态,您 "replay" 日志文件:从文件中读取条目,并更新内存中文件操作的状态。到达日志末尾后,内存中的状态应该是最新的并准备好恢复。该方法的典型复杂性是,由于仅写入日志文件,因此必须定期清理它,从中清除旧的已完成操作。 (最简单的方法是在恢复时进行清理(恢复后,写入新日志,删除旧日志),然后定期优雅地重启应用程序。)