linux - pthread 读写器锁和基于 fcntl() 的文件锁有什么区别?

标签 linux locking pthreads fcntl

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

最佳答案

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

TL;博士:
fcntl(2) :

  • 咨询锁定接口(interface)
  • 主要适用于文件
  • 在多个进程之间轻松工作
  • pthread_rwlock :
  • 咨询锁定接口(interface)
  • 序列化对冲突操作(写入/读取、写入/写入、读取/写入)的访问
  • 为单个进程中的多个线程之间的共享资源(内存、文件描述符等)提供安全性
  • fcntl(2) -based 锁对文件或文件中的字节范围实现 POSIX 建议锁。由于它们是建议性的,因此没有任何东西强制执行这些锁——所有进程(或线程)必须合作并尊重锁的语义才能使它们生效。例如,考虑两个进程 AB对某个文件进行操作 f .如果处理A设置锁定 f , B可以完全忽略这些锁,为所欲为。通常,此接口(interface)用于保护多个线程和/或进程之间对整个文件(或文件内的范围)的访问。
    pthread_rwlock接口(interface)也可以被认为是一个咨询锁定系统(所有线程都必须使用 API 才能使锁定生效)。但是,它不是在文件之上实现的,并且不限于保护对文件的访问。读写锁是共享内存互斥接口(interface)的一种形式,这样多个读者可以同时执行一个临界区,而写者被阻塞,或者单个写者可以执行一个临界区,阻塞所有其他并发的读者和写者。通常,此接口(interface)用于保护以读取为主的工作负载中进程中多个线程之间对共享可变状态(可能是共享内存,可能是文件访问)的访问。此 API 通常不用于保护多个进程中的并发访问。

    如果我面临选择这些接口(interface)之一来序列化对某些数据的访问的决定,我希望至少问自己几个问题:
  • 我主要处理文件吗?
  • 我有多个进程吗?

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

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

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

    关于linux - pthread 读写器锁和基于 fcntl() 的文件锁有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37172033/

    相关文章:

    linux - execlp 用户库函数

    linux - 在 Ubuntu 上设置 Angular CLI

    linux - 如何使用终端从网站下载视频

    python - 通过python授予USB权限

    c - Helgrind 报告单线程上的数据争用

    java - Neo4j:通过 Java API 或 Cypher 显式悲观锁定

    Java 类级锁与对象级锁

    c# - 等待锁定执行的任务数组

    c - 分离与可连接 POSIX 线程

    c++ - 如何在 linux 上获取在 "black box"中创建的线程数?