• 自旋锁和读写锁


    自旋锁概念

            ​何谓自旋锁?它是为实现保护共享资源而提出一种锁机制。其实,自旋锁与互斥锁比较类似,它们都是为了解决对某项资源的互斥使用。无论是互斥锁,还是自旋锁,在任何时刻,最多只能有一个保持者,也就说,在任何时刻最多只能有一个执行单元获得锁。但是两者在调度机制上略有不同。对于互斥锁,如果资源已经被占用,资源申请者只能进入睡眠状态。但是自旋锁不会引起调用者睡眠,如果自旋锁已经被别的执行单元保持,调用者就一直循环在那里看是否该自旋锁的保持者已经释放了锁,“自旋”一词就是因此而得名。

    自旋锁_百度百科 (baidu.com)icon-default.png?t=N7T8https://baike.baidu.com/item/%E8%87%AA%E6%97%8B%E9%94%81/9137985?fr=ge_ala        

            对于自旋锁来说,它只需要消耗很少的资源来建立锁;随后当线程被阻塞时,它就会一直重复检查看锁是否可用了,也就是说当自旋锁处于等待状态时它会一直消耗CPU时间。

            对于互斥锁来说,与自旋锁相比它需要消耗大量的系统资源来建立锁;随后当线程被阻塞时,线程的调度状态被修改,并且线程被加入等待线程队列;最后当锁可用时,在获取锁之前,线程会被从等待队列取出并更改其调度状态;但是在线程被阻塞期间,它不消耗CPU资源。

            因此自旋锁和互斥锁适用于不同的场景。自旋锁适用于那些仅需要阻塞很短时间的场景,而互斥锁适用于那些可能会阻塞很长时间的场景。

    自旋锁相关api

    1. #include
    2. //创建锁
    3. pthread_spinlock_t spinlock_t;
    4. //初始化自旋锁
    5. int pthread_spin_init(pthread_spinlock_t *lock, int pshared);
    6. //销毁自旋锁
    7. int pthread_spin_destroy(pthread_spinlock_t *lock);
    8. //加锁
    9. int pthread_spin_lock(pthread_spinlock_t *lock);
    10. //解锁
    11. int pthread_spin_unlock(pthread_spinlock_t *lock);
    12. //非阻塞
    13. int pthread_spin_trylock(pthread_spinlock_t *lock);

    pshared取值:
            PTHREAD_PROCESS_SHARED:该自旋锁可以在多个进程中的线程之间共享。(可以被其他进程中的线程看到)
            PTHREAD_PROCESS_PRIVATE:仅初始化本自旋锁的线程所在的进程内的线程才能够使用该自旋锁

    读写锁概念

            读写锁实际是一种特殊的自旋锁,它把对共享资源的访问者划分成读者和写者,读者只对共享资源进行读访问,写者则需要对共享资源进行写操作。

            如果读写锁当前没有读者,也没有写者,那么写者可以立刻获得读写锁,否则它必须自旋在那里,直到没有任何写者或读者。如果读写锁没有写者,那么读者可以立即获得该读写锁,否则读者必须自旋在那里,直到写者释放该读写锁。

    读写锁_百度百科 (baidu.com)icon-default.png?t=N7T8https://baike.baidu.com/item/%E8%AF%BB%E5%86%99%E9%94%81/1756708?fr=ge_ala

    读写锁相关api

    1. //初始化锁
    2. int pthread_rwlock_init(pthread_rwlock_t *restrict rwlock, const pthread_rwlockattr_t *restrict attr);
    3. //销毁锁
    4. int pthread_rwlock_destroy(pthread_rwlock_t *rwlock);
    5. //获取读锁
    6. int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock);
    7. //获取写锁
    8. int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock);
    9. //释放锁
    10. int pthread_rwlock_unlock(pthread_rwlock_t *rwlock);
    11. //非阻塞获取
    12. int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock);
    13. int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock);

    自旋锁代码示例

    1. #include
    2. #include
    3. pthread_spinlock_t spin;
    4. void *func1()
    5. {
    6. int i;
    7. pthread_spin_lock(&spin);
    8. for(i=0;i<5;i++)
    9. {
    10. printf("t1 id:%ld\n",(unsigned long)pthread_self());
    11. }
    12. printf("========================\n");
    13. pthread_spin_unlock(&spin);
    14. }
    15. void *func2()
    16. {
    17. pthread_spin_lock(&spin);
    18. printf("t2 id:%ld\n",(unsigned long)pthread_self());
    19. pthread_spin_unlock(&spin);
    20. }
    21. void *func3()
    22. {
    23. pthread_spin_lock(&spin);
    24. printf("t3 id:%ld\n",(unsigned long)pthread_self());
    25. pthread_spin_unlock(&spin);
    26. }
    27. int main()
    28. {
    29. pthread_t t1;
    30. pthread_t t2;
    31. pthread_t t3;
    32. pthread_spin_init(&spin,PTHREAD_PROCESS_SHARED);
    33. pthread_create(&t1, NULL, func1,NULL);
    34. pthread_create(&t2, NULL, func2,NULL);
    35. pthread_create(&t3, NULL, func3,NULL);
    36. pthread_join(t1,NULL);
    37. pthread_join(t2,NULL);
    38. pthread_join(t3,NULL);
    39. pthread_spin_destroy(&spin);
    40. return 0;
    41. }

    编译运行可以看到 func1运行5次放锁后 t2和t3才运行

  • 相关阅读:
    RuntimeError: DataLoader worker (pid(s) 46220) exited unexpectedly
    【C++】位图(海量数据处理)
    Element常用api webview
    【map的实际应用,学习map,不用=白学】3302. 表达式求值【如何得到运算符优先级?自己过一遍示例即可明白】【怎么比较运算符的优先级?map】
    vue3使用pinia 实现权限code存取
    安装Anaconda与pytorch,在IDEA中配置环境进行编程
    【开源】基于Vue和SpringBoot的创意工坊双创管理系统
    Oracle中的commit与rollback
    网络练习题带答案
    针对U盘文件的盗与防攻略
  • 原文地址:https://blog.csdn.net/2301_77164542/article/details/133960300