插件窝 干货文章 linux线程锁有几种

linux线程锁有几种

线程 pthread 场景 互斥 735    来源:    2025-04-18

在 Linux 系统中,线程锁(线程同步机制)主要有以下几种类型,每种锁适用于不同的并发场景:


1. 互斥锁(Mutex)

  • 作用:确保同一时间只有一个线程能访问共享资源。
  • 特点
    • 阻塞机制:未获取锁的线程会阻塞等待。
    • 不可重入:默认情况下,同一线程重复加锁会导致死锁(但可通过属性配置为可重入锁)。
  • 相关函数c pthread_mutex_init() / pthread_mutex_lock() / pthread_mutex_unlock() / pthread_mutex_destroy()
  • 适用场景:对共享资源的独占访问(如全局变量、数据结构等)。

2. 自旋锁(Spinlock)

  • 作用:通过忙等待(Busy-Waiting)实现同步,线程不会主动让出CPU。
  • 特点
    • 非阻塞忙等待:适合短时间锁持有场景。
    • 无上下文切换开销,但会占用CPU资源。
  • 相关函数c pthread_spin_init() / pthread_spin_lock() / pthread_spin_unlock() / pthread_spin_destroy()
  • 适用场景:多核CPU环境,锁持有时间极短(如内核态操作、高性能场景)。

3. 读写锁(Read-Write Lock)

  • 作用:区分读操作和写操作,允许多个读线程并发,但写线程独占。
  • 特点
    • 读共享:多个线程可同时持有读锁。
    • 写独占:写锁会阻塞其他所有读写锁。
  • 相关函数c pthread_rwlock_init() / pthread_rwlock_rdlock() / pthread_rwlock_wrlock() / pthread_rwlock_unlock()
  • 适用场景:读多写少的场景(如缓存、配置文件读取)。

4. 条件变量(Condition Variable)

  • 作用:允许线程在某个条件不满足时主动阻塞,等待其他线程唤醒。
  • 特点
    • 必须与互斥锁配合使用。
    • 通过 pthread_cond_wait() 主动释放锁并进入等待,被唤醒后重新获取锁。
  • 相关函数c pthread_cond_init() / pthread_cond_wait() / pthread_cond_signal() / pthread_cond_broadcast()
  • 适用场景:线程间协作(如生产者-消费者模型)。

5. 屏障(Barrier)

  • 作用:同步多个线程,所有线程到达屏障点后才能继续执行。
  • 特点
    • 适用于分阶段并行任务。
  • 相关函数c pthread_barrier_init() / pthread_barrier_wait() / pthread_barrier_destroy()
  • 适用场景:多线程协同计算(如MapReduce分阶段处理)。

6. 信号量(Semaphore)

  • 作用:通过计数器控制线程并发数(POSIX信号量)。
  • 特点
    • 分为有名信号量(进程间共享)和无名信号量(线程间共享)。
    • 支持 Psem_wait)和 Vsem_post)操作。
  • 相关函数c sem_init() / sem_wait() / sem_post() / sem_destroy()
  • 适用场景:限制资源并发访问数量(如线程池任务队列)。

7. 文件锁(fcntl/flock)

  • 作用:对文件或文件区域加锁(进程间同步)。
  • 特点
    • 分为建议性锁(Advisory)和强制性锁(Mandatory)。
  • 相关函数c fcntl() / flock()
  • 适用场景:多进程访问同一文件的同步。

选择锁的建议

  1. 简单独占访问 → 互斥锁(Mutex)。
  2. 高频短时锁 → 自旋锁(Spinlock)。
  3. 读多写少 → 读写锁(RW Lock)。
  4. 线程协作 → 条件变量 + 互斥锁。
  5. 限制并发数 → 信号量(Semaphore)。

注意事项

  • 避免死锁:确保锁的获取和释放顺序一致。
  • 性能权衡:自旋锁 vs 互斥锁取决于锁持有时间。
  • 可重入性:默认互斥锁不可重入,需通过属性设置 PTHREAD_MUTEX_RECURSIVE

根据具体场景选择合适的锁机制,可以显著提升多线程程序的性能和可靠性。