对于项目,我正在考虑使用pthread reader-writer locks
或fcntl()-based file locks
。我必须选择它们。你能解释一下它们之间的区别吗?有哪些优点和缺点?
答案 0 :(得分:2)
它们是两种完全不同的工具,通常用于不同的任务。两者之间的公平或完全对比是困难的,因为它就像比较苹果和沙发。
TL; DR:
fcntl(2)
:
pthread_rwlock
:
fcntl(2)
- 基于锁对文件或文件中的字节范围实施POSIX建议锁。因为它们是建议性的,所以没有任何东西强制执行这些锁 - 所有进程(或线程)必须合作并尊重锁的语义才能使它们有效。例如,考虑在某个文件A
上运行的两个进程B
和f
。如果进程A
在f
上设置了锁,B
可以完全忽略这些锁并执行任何喜欢的操作。通常,此接口用于保护对多个线程和/或进程之间的整个文件(或文件中的范围)的访问。
pthread_rwlock
接口也可以被视为咨询锁定系统(所有线程必须使用API才能使锁定生效)。但是,它不是在文件之上实现的,并且不限于保护对文件的访问的范围。读写器锁是共享存储器互斥接口的一种形式,使得多个读取器可以在写入器被阻止时同时执行关键部分,或者使得各个写入器可以执行关键部分,阻止所有其他并发读取器和写入器。通常,此接口用于保护对读取主要工作负载中进程中多个线程之间的共享可变状态(可能是共享内存,可能是文件访问)的访问。此API通常不用于保护多个进程中的并发访问。
如果我面临选择其中一个界面来序列化访问某些数据的决定,我会问自己至少有几个问题:
如果意图主要是为了保护对文件的访问,但只是在一个进程中,我可能会决定使用pthread_rwlock
。这种方法的缺点是,如果将来需要使用多个进程来访问该文件,我就没有好的方法来表达我对其他进程的锁定意图。同样,如果我主要尝试序列化对某些共享内存的访问,我会使用pthread_rwlock
,因为fcntl(2)
接口表达了对文件的某些意图。
当尝试在读取和写入单个文件的多个进程之间进行协作时,我可能会使用fcntl(2)
。但是,这可能会很快变得非常复杂。例如,如何处理截断等事件?考虑这样一种情况:进程A
已将1024字节读入文件,然后由进程B
截断为0字节。然后A
必须寻找文件的开头并等待写入新数据以继续读取而不会出错 - 或者正确附加新数据本身!
解决这些问题需要在其他文件中进行更多的锁定通信,并且复杂性可能会迅速失控。如果我需要在文件上实现某种并发系统,我可能会选择多个线程并使用pthread_rwlock
API。管理在单个进程中实现此类系统所需的全部更新变得更加容易。在不了解您所面临的要求的情况下,以这种或那种方式进行指导是相当困难的。