服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

Linux|Centos|Ubuntu|系统进程|Fedora|注册表|Bios|Solaris|Windows7|Windows10|Windows11|windows server|

服务器之家 - 服务器系统 - Linux - linux中各种锁机制的使用与区别详解

linux中各种锁机制的使用与区别详解

2022-08-11 08:44wangle965235568 Linux

这篇文章主要给大家介绍了关于linux中各种锁机制的使用与区别的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

前言:

相信需要了解这方面的知识的小伙伴,已经基本对进程间通信和线程间通信有了一定了解。例如,进程间通信的机制之一:共享内存(在这里不做详解):多个进程可同时访问同一块内存。如果不对访问这块内存的临界区进行互斥或者同步,那么进程的运行很可能出现一些不可预知的错误和结果。

接下来我们了解三种常见的Linux下的互斥操作—>锁。

1.互斥锁(mutex)

特点:对于读者和写者来说。只要有一方获取了锁,另一方则不能继续获取,进而执行临界区代码。

创建锁:

有两种方法创建互斥锁,静态方式和动态方式。POSIX定义了一个宏PTHREAD_MUTEX_INITIALIZER 来静态初始化互斥锁,

方法如下:

?
1
pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER;

在LinuxThreads实现中,pthread_mutex_t是一个结构,而PTHREAD_MUTEX_INITIALIZER则是一个结构常量。

动态方式是采用pthread_mutex_init()函数来初始化互斥锁,API定义如下:

?
1
int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t*mutexattr)

其中mutexattr用于指定互斥锁属性(见下),如果为NULL则使用缺省属性。 pthread_mutex_destroy ()用于注销一个互斥锁,API定义如下:

?
1
int pthread_mutex_destroy(pthread_mutex_t *mutex)

锁操作主要包括加锁pthread_mutex_lock()、解锁pthread_mutex_unlock()和测试加锁 pthread_mutex_trylock()三个,不论哪种类型的锁,都不可能被两个不同的线程同时得到, 而必须等待解锁。对于普通锁和适应锁类型,解锁者可以是同进程内任何线程; 而检错锁则必须由加锁者解锁才有效,否则返回EPERM;对于嵌套锁,文档和实现要求必须由 加锁者解锁,但实验结果表明并没有这种限制,这个不同目前还没有得到解释。在同一进程中 的线程,如果加锁后没有解锁,则任何其他线程都无法再获得锁。

?
1
2
3
int pthread_mutex_lock(pthread_mutex_t *mutex)
int pthread_mutex_unlock(pthread_mutex_t *mutex)
int pthread_mutex_trylock(pthread_mutex_t *mutex)

pthread_mutex_trylock() 语义与pthread_mutex_lock()类似,不同的是在锁已经被占据时返回 EBUSY而不是挂起等待。
例如:单例模式下,线程安全的加锁:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class SingleTon
{
public:
static SingleTon* getInstance()
{
pthread_mutex_lock(&mutex);
if(mpSingle == NULL)
{
mpSingleTon = new SingleTon();
}
pthread_mutex_unlock(&mutex);
return mpSingleTon;
}
private:
SingleTon(){};
~SingleTon(){pthread_mutex_desttroy(&mutex,NULL);}
static pthread_mutex_t mutex;
static SingleTon * mpSingleTon;
}
pthread_mutex_t SingleTon::mutex = PTHREAD_MUTEX_INITIALIZER;
SingleTon * SingleTon::mpSingleTon = NULL;

优点:

由一块能够被多个进程共享的内存空间(一个对齐后的整型变量)组成;这个整型变量的值能够通过汇编语言调用CPU提供的原子操作指令来增加或减少,并且一个进程可以等待直到那个值变成正数。 的操作几乎全部在应用程序空间完成;只有当操作结果不 一致从而需要仲裁时,才需要进入操作系统内核空间执行。这种机制允许使用的锁定原语有非常高的执行效率:由于绝大多数 的操作并不需要在多个进程之间进行仲裁,所以绝大多数操作都可以在应用程序空间执行,而不需要使用(相对高代价的)内核系统调
用。

2.读写锁

特点:读写锁适合于对数据结构的读次数比写次数多得多的情况.因为,读模式锁定时可以共享,以写 模式锁住时意味着独占,所以读写锁又叫共享-独占锁.

初始化和销毁:

?
1
2
3
int pthread_rwlock_init(pthread_rwlock_t *restrict rwlock, const
pthread_rwlockattr_t *restrict attr);
int pthread_rwlock_destroy(pthread_rwlock_t *rwlock);

成功则返回0,出错则返回错误编号. 同互斥量以上,在释放读写锁占用的内存之前,需要先通过 pthread_rwlock_destroy对读写锁进行清理工作, 释放由init分配的资源.

读和写:

?
1
2
3
int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock);
int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock);
int pthread_rwlock_unlock(pthread_rwlock_t *rwlock);

成功则返回0,出错则返回错误编号.这3个函数分别实现获取读锁,获取写锁和释放锁的操作.获 取锁的两个函数是阻塞操作,同样,非阻塞的函数为:

?
1
2
int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock);
int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock);

成功则返回0,出错则返回错误编号.非阻塞的获取锁操作,如果可以获取则返回0,否则返回 错误的EBUSY.

3.自旋锁

特点:轮询忙等待。

在单核cpu下不起作用:被自旋锁保护的临界区代码执行时不能进行挂起状态。会造成死锁
自旋锁的初衷就是:在短期间内进行轻量级的锁定。一个被争用的自旋锁使得请求它的线程在等待锁重新可用的期间进行自旋(特别浪费处理器时间),所以自旋锁不应该被持有时间过长。如果需要长时间锁定的话, 最好使用信号量。

API:

linux中各种锁机制的使用与区别详解

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对服务器之家的支持。

原文链接:https://blog.csdn.net/wangle965235568/article/details/78358942

延伸 · 阅读

精彩推荐
  • Linux详解Linux文件系统:ext4及更高版本

    详解Linux文件系统:ext4及更高版本

    今天小编就为大家分享一篇关于Linux文件系统:ext4及更高版本的详解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟...

    Jim Salter3552022-07-22
  • Linuxiptables建立规则和链的基本方法

    iptables建立规则和链的基本方法

    这篇文章主要介绍了iptables建立规则和链的基本方法,iptables是常用的Linux集成的IP过滤规则系统,需要的朋友可以参考下...

    大步's blog2892019-09-06
  • Linux一张图看尽Linux内核运行原理

    一张图看尽Linux内核运行原理

    一张图看尽Linux内核运行原理,帮助大家了解Linux内核运行原理,通过这张图,你可以很方便地学习内核知识,需要的朋友可以参考下...

    Linux Story10882021-10-29
  • LinuxLinux配置VSFTP服务器的方法

    Linux配置VSFTP服务器的方法

    下面小编就为大家带来一篇Linux配置VSFTP服务器的方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧...

    Linux教程网11242021-12-10
  • Linux在Linux系统上实现IP转发的方法

    在Linux系统上实现IP转发的方法

    这篇文章主要介绍了在Linux系统上实现IP转发的方法,是Linux入门学习中的基础知识,需要的朋友可以参考下...

    开源中文社区10232019-09-08
  • Linux在 Linux 上运行你最喜欢的 Windows 应用程序

    在 Linux 上运行你最喜欢的 Windows 应用程序

    WINE 是一个开源项目,它可以协助很多 Windows 应用程序在 Linux 上运行,就好像它们是原生程序一样。...

    Linux中国7292021-03-09
  • Linuxlinux系统下的时间配置综述

    linux系统下的时间配置综述

    这篇文章主要给大家介绍了关于linux系统下时间配置的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需...

    仁人3672022-08-11
  • LinuxLinux内核中dev_info、dev_dbg、dev_err及动态调试

    Linux内核中dev_info、dev_dbg、dev_err及动态调试

    目前在kernel驱动代码中,都不再建议直接使用printk直接添加打印信息,而是使用dev_info,dev_dbg,dev_err之类的函数代替....

    一口Linux13472021-04-25