Linux下的多线程编程:原理、工具及应用(5)

本文详细介绍了自旋锁和读写锁在并发编程中的原理、使用场景、性能优劣以及相关函数如pthread_spinlock_t、pthread_rwlock_t的用法。特别探讨了自旋锁的忙等待策略和可能带来的死锁风险。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

                                               🎬慕斯主页修仙—别有洞天

                                              ♈️今日夜电波:Flower of Life—陽花

                                                                0:34━━━━━━️💟──────── 4:46
                                                                    🔄   ◀️   ⏸   ▶️    ☰  

                                      💗关注👍点赞🙌收藏您的每一次鼓励都是对我莫大的支持😍


 

目录

自旋锁

什么是自旋锁?

pthread_spinlock_t

pthread_spin_init

pthread_spin_lock

pthread_spin_unlock

pthread_spin_trylock

pthread_spin_destroy

读写锁

pthread_rwlock_t

pthread_rwlock_init

pthread_rwlock_destroy

pthread_rwlock_rdlock

pthread_rwlock_wrlock

pthread_rwlock_unlock

pthread_rwlock_tryrdlock

pthread_rwlock_trywrlock


自旋锁

什么是自旋锁?

        自旋锁是一种同步机制,它用于控制多线程环境中对共享资源的访问。

        自旋锁的核心思想是,当一个线程试图获取已经被其他线程持有的锁时,而不是进入阻塞状态,它会在一个循环中不断地检查锁是否可用。一旦锁被释放,这个线程就可以立即获取锁并继续执行。这种机制避免了线程切换的开销,因此在某些情况下可以提高性能。以下是对自旋锁的详细解释:

  1. 不阻塞线程:自旋锁不会使线程进入睡眠状态,而是在用户态进行忙等待。
  2. 适用场景:自旋锁适用于锁持有时间较短的场景,这样等待的线程可以在不久的将来获得锁,而不会浪费太多时间在线程切换上。
  3. 避免上下文切换:由于线程在等待锁时不会进入内核态,因此避免了操作系统进程调度和线程切换的消耗。
  4. 适用性:自旋锁通常用在操作系统内核或其他需要快速响应的场景中,因为它们可以在没有其他线程持有锁的情况下迅速获取锁。
  5. 死锁风险:自旋锁可能会导致死锁,如果多个线程都在无限期地等待同一个资源,这可能导致系统无法正常工作。
  6. 性能考量:自旋锁的性能优势在于减少了线程切换的开销,但如果锁持有时间过长,自旋锁可能会导致CPU资源的浪费。
  7. 实现方式:自旋锁可以通过原子操作来实现,确保在多线程环境下对锁的安全访问。
  8. 与互斥锁的区别:与互斥锁相比,自旋锁在获取锁失败时不会让线程进入睡眠状态,而是保持忙碌等待,这可以减少线程切换的开销,但在锁竞争激烈时可能会增加CPU使用率。

        自旋锁是一种高效的同步机制,适用于锁持有时间短且希望减少线程切换开销的场景。然而,它也有自己的局限性,如可能增加CPU使用率和潜在的死锁风险,因此在使用时需要根据具体情况谨慎选择。

pthread_spinlock_t

pthread_spinlock_t 是一个用于表示自旋锁的数据类型。它通常用于多线程编程中,用于保护共享资源的访问。

在多线程环境中,多个线程可能会同时访问同一个共享资源,这可能导致数据竞争和不一致的结果。为了避免这种情况,可以使用自旋锁来确保在同一时刻只有一个线程能够访问共享资源。

pthread_spinlock_t 是一个无符号整型变量,用于存储自旋锁的状态。它通常与 pthread_spin_init()、pthread_spin_destroy()、pthread_spin_lock() 和 pthread_spin_unlock() 等函数一起使用。

pthread_spin_init

pthread_spin_init 是一个用于初始化自旋锁的函数。它的作用是为一个自旋锁分配内存并初始化其属性。

函数原型:

int pthread_spin_init(pthread_spinlock_t *lock, int pshared);

参数说明:

  • lock:指向要初始化的自旋锁变量的指针。
  • pshared:指定自旋锁的共享属性。如果设置为 PTHREAD_PROCESS_PRIVATE,则该自旋锁只能在同一个进程中的线程之间共享;如果设置为 PTHREAD_PROCESS_SHARED,则该自旋锁可以在不同的进程中的线程之间共享。

返回值:

  • 成功时,返回0;
  • 失败时,返回一个非零的错误码。

pthread_spin_lock

pthread_spin_lock() 是一个用于获取自旋锁的函数。它的作用是尝试获取一个自旋锁,如果锁已经被其他线程持有,则当前线程会进入忙等待状态,不断循环检查锁是否可用,直到获取到锁为止。

函数原型:

int pthread_spin_lock(pthread_spinlock_t *lock);

参数说明:

  • lock:指向要获取的自旋锁变量的指针。

返回值:

  • 成功时,返回0;
  • 失败时,返回一个非零的错误码。

pthread_spin_unlock

pthread_spin_unlock() 是一个用于释放自旋锁的函数。它的作用是释放一个已经获取到的自旋锁,使得其他等待该锁的线程可以继续执行。

函数原型:

int pthread_spin_unlock(pthread_spinlock_t *lock);

参数说明:

  • lock:指向要释放的自旋锁变量的指针。

返回值:

  • 成功时,返回0;
  • 失败时,返回一个非零的错误码。

pthread_spin_trylock

pthread_spin_trylock() 是一个用于尝试获取自旋锁的函数。它的作用是尝试获取一个自旋锁,如果锁已经被其他线程持有,则立即返回失败,不会进入忙等待状态。

函数原型:

int pthread_spin_trylock(pthread_spinlock_t *lock);

参数说明:

  • lock:指向要尝试获取的自旋锁变量的指针。

返回值:

  • 成功时,返回0;
  • 失败时,返回一个非零的错误码。

pthread_spin_destroy

pthread_spin_destroy() 是一个用于销毁自旋锁的函数。它的作用是释放一个已经初始化的自旋锁,以便系统可以回收其占用的资源。

函数原型:

int pthread_spin_destroy(pthread_spinlock_t *lock);

参数说明:

  • lock:指向要销毁的自旋锁变量的指针。

返回值:

  • 成功时,返回0;
  • 失败时,返回一个非零的错误码。

读写锁

pthread_rwlock_t

        pthread_rwlock_t 是一个用于实现读写锁的数据类型,它是POSIX线程库中的一部分。读写锁允许多个线程同时读取共享资源,但在写入时只允许一个线程进行操作。

        读写锁有两种状态:读锁定和写锁定。当一个线程获取读锁定时,其他线程可以继续获取读锁定或等待获取写锁定。当一个线程获取写锁定时,其他线程不能获取读锁定或写锁定,直到写锁定被释放。

        使用 pthread_rwlock_t 需要先初始化读写锁,然后可以使用 pthread_rwlock_init() 函数进行初始化。在不再需要读写锁时,应使用 pthread_rwlock_destroy() 函数销毁它。

        以下是一些常用的读写锁操作函数:

  1. pthread_rwlock_init():初始化读写锁。
  2. pthread_rwlock_destroy():销毁读写锁。
  3. pthread_rwlock_rdlock():获取读锁定。
  4. pthread_rwlock_tryrdlock():尝试获取读锁定,如果无法获取则立即返回。
  5. pthread_rwlock_timedrdlock():在指定时间内尝试获取读锁定,如果无法获取则返回。
  6. pthread_rwlock_wrlock():获取写锁定。
  7. pthread_rwlock_trywrlock():尝试获取写锁定,如果无法获取则立即返回。
  8. pthread_rwlock_timedwrlock():在指定时间内尝试获取写锁定,如果无法获取则返回。
  9. pthread_rwlock_unlock():释放锁定。

pthread_rwlock_init

pthread_rwlock_init() 是一个用于初始化读写锁的函数。它的作用是为一个已经声明的读写锁变量分配内存并初始化其属性。

函数原型:

int pthread_rwlock_init(pthread_rwlock_t *restrict rwlock, const pthread_rwlockattr_t *restrict attr);

参数说明:

  • rwlock:指向要初始化的读写锁变量的指针。
  • attr:指向读写锁属性对象的指针,如果传入NULL,则使用默认属性。

返回值:

  • 成功时,返回0;
  • 失败时,返回一个非零的错误码。

pthread_rwlock_destroy

pthread_rwlock_destroy() 是一个用于销毁读写锁的函数。它的作用是释放一个已经初始化的读写锁变量所占用的资源。

函数原型:

c复制代码运行
int pthread_rwlock_destroy(pthread_rwlock_t *rwlock);

参数说明:

  • rwlock:指向要销毁的读写锁变量的指针。

返回值:

  • 成功时,返回0;
  • 失败时,返回一个非零的错误码。

pthread_rwlock_rdlock

pthread_rwlock_rdlock() 是一个用于获取读锁定的函数。它的作用是尝试获取一个读写锁的读锁定,如果锁已经被写锁定或者有其他线程正在等待获取写锁定,则当前线程会进入阻塞状态,直到获取到读锁定为止。

函数原型:

int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock);

参数说明:

  • rwlock:指向要获取读锁定的读写锁变量的指针。

返回值:

  • 成功时,返回0;
  • 失败时,返回一个非零的错误码。

pthread_rwlock_wrlock

pthread_rwlock_wrlock() 是一个用于获取写锁定的函数。它的作用是尝试获取一个读写锁的写锁定,如果锁已经被其他线程获取了读锁定或者写锁定,则当前线程会进入阻塞状态,直到获取到写锁定为止。

函数原型:

int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock);

参数说明:

  • rwlock:指向要获取写锁定的读写锁变量的指针。

返回值:

  • 成功时,返回0;
  • 失败时,返回一个非零的错误码。

pthread_rwlock_unlock

pthread_rwlock_unlock() 是一个用于释放读写锁的函数。它的作用是释放一个已经获取到的读写锁,使得其他线程可以获取该锁。

函数原型:

int pthread_rwlock_unlock(pthread_rwlock_t *rwlock);

参数说明:

  • rwlock:指向要释放的读写锁变量的指针。

返回值:

  • 成功时,返回0;
  • 失败时,返回一个非零的错误码。

pthread_rwlock_tryrdlock

pthread_rwlock_tryrdlock() 是一个用于尝试获取读锁定的函数。它的作用是尝试获取一个读写锁的读锁定,如果锁已经被其他线程获取了写锁定,则当前线程不会进入阻塞状态,而是立即返回错误码。

函数原型:

int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock);

参数说明:

  • rwlock:指向要尝试获取读锁定的读写锁变量的指针。

返回值:

  • 成功时,返回0;
  • 失败时,返回一个非零的错误码。

pthread_rwlock_trywrlock

pthread_rwlock_trywrlock() 是一个用于尝试获取写锁定的函数。它的作用是尝试获取一个读写锁的写锁定,如果锁已经被其他线程获取了读锁定或写锁定,则当前线程不会进入阻塞状态,而是立即返回错误码。

函数原型:

int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock);

参数说明:

  • rwlock:指向要尝试获取写锁定的读写锁变量的指针。

返回值:

  • 成功时,返回0;
  • 失败时,返回一个非零的错误码。

 


                       感谢你耐心的看到这里ღ( ´・ᴗ・` )比心,如有哪里有错误请踢一脚作者o(╥﹏╥)o! 

                                       

                                                                        给个三连再走嘛~  

评论 24
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

慕斯( ˘▽˘)っ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值