pthread reader-writer 锁和基于 fcntl() 的文件锁有什么区别?

What are the differences between pthread reader-writer locks and fcntl()-based file locks?

对于我正在考虑使用 pthread reader-writer locksfcntl()-based file locks 的项目。我必须从中选择。你能解释一下它们之间的区别吗?有什么优点和缺点?

它们是两种完全不同的工具,通常用于不同的任务。两者之间的公平或完全对比是困难的,因为这就像将苹果与沙发进行比较。

长话短说:

fcntl(2):

  • 咨询锁定界面
  • 主要处理文件
  • 在多个进程之间轻松工作

pthread_rwlock:

  • 咨询锁定界面
  • 序列化对冲突操作的访问(writes/reads、writes/writes、reads/writes)
  • 为单个进程中多个线程之间的共享资源(内存、文件描述符等)提供安全性
基于

fcntl(2) 的锁在文件或文件中的字节范围上实现 POSIX 建议锁。由于它们是建议性的,因此没有任何东西强制执行这些锁——所有进程(或线程)都必须合作并遵守锁的语义才能使它们有效。例如,考虑两个进程 AB 在某个文件 f 上运行。如果进程Af上设置了锁,B可以完全忽略这些锁并为所欲为。通常,此接口用于保护多个线程和/或进程之间对整个文件(或文件内的范围)的访问。

pthread_rwlock 接口也可以被认为是一个咨询锁定系统(所有线程必须使用 API 才能使锁定有效)。但是,它不是在文件之上实现的,并且不限于保护对文件的访问的范围。 reader-writer 锁是共享内存互斥接口的一种形式,这样多个 readers 可以同时执行一个临界区,而 writer 被阻塞,或者单个 writer 可以执行一个临界区,阻塞所有其他并发的 reader 和作者。通常,此接口用于保护在以读取为主的工作负载中进程中的多个线程之间对共享可变状态(可能是共享内存,可能是文件访问)的访问。 API 通常不用于保护多个进程中的并发访问。

如果我要决定选择其中一个接口来序列化对某些数据的访问,我希望至少问自己几个问题:

  • 我主要处理文件吗?
  • 我有多个进程吗?

如果主要目的是保护对文件的访问,但仅在单个进程中,我可能会满足于使用 pthread_rwlock。这种方法的缺点是,如果我将来需要使用多个进程来访问该文件,我将没有一个好的方法来向其他进程表达我的锁定意图。同样,如果我主要尝试序列化对某些共享内存的访问,我会使用 pthread_rwlock,因为 fcntl(2) 接口表达了对文件的一些意图。

当尝试在多个进程之间协作读写单个文件时,我可能会使用fcntl(2)。然而,这可能会变得非常复杂、非常快。例如,如何处理截断之类的事件?考虑这样一种情况,进程 A 已将 1024 字节读入一个文件,然后该文件被进程 B 截断为 0 字节。 A 然后必须查找文件的开头并等待写入新数据以继续读取而不会出错——或者正确地附加新数据本身!

解决这些问题需要在额外的文件中进行更多的锁定通信,并且复杂性会很快失控。如果我需要实现某种处理文件的并发系统,我可能会选择多线程并使用 pthread_rwlock API。在单个进程中管理实施此类系统所需的全部更新更容易。在不知道您面临的要求的情况下,很难以一种或另一种方式进行指导。