悲观锁、乐观锁、自旋锁和读写锁

news2024/11/25 22:28:15

悲观锁和乐观锁

悲观锁:在每次取数据时,总是担心数据会被其他线程修改,所以会在取数据前先加锁(读锁,写锁,行 锁等),当其他线程想要访问数据时,被阻塞挂起。(互斥锁就是一种悲观锁)

乐观锁:每次取数据时候,总是乐观的认为数据不会被其他线程修改,因此不上锁。但是在更新数据前, 会判断其他数据在更新前有没有对数据进行修改。主要采用两种方式:版本号机制和CAS操作。(C++原子操作是基于CAS的乐观锁)

自旋锁

 

由于挂起等待也有一定的消耗,万一在挂起时直接再次申请锁就成功了,挂起锁的消耗就更高。自旋锁类似于在加锁时采用:

while(pthread_mutex_trylock(&mutex));

的方式加锁。很有可能会反复申请锁,浪费CPU资源,只有在临界区的时间特别短才能使用

比如抢票代码:

#include<iostream>
#include<pthread.h> 
#include<vector>
#include<string>
#include<unistd.h>
using namespace std;
int ticket = 1000;
class mutexGuard
{
public:
    mutexGuard(pthread_spinlock_t* pmutex)
    {
        _pmutex = pmutex;
        pthread_spin_lock(_pmutex);
    }
    ~mutexGuard()
    {
        pthread_spin_unlock(_pmutex);
    }
private:
    pthread_spinlock_t* _pmutex;

};

class threadDate
{
public:
    threadDate(const string& name, pthread_spinlock_t* pmutex)
    :_name(name)
    ,_pmutex(pmutex)
    {}
    string _name;
    pthread_spinlock_t* _pmutex;
};

void* getTicket(void* args)
{
    threadDate* td = static_cast<threadDate*>(args);
    while(ticket > 0)
    {
        
        {
            mutexGuard mg = mutexGuard(td->_pmutex);
            if(ticket > 0)
            {
                usleep(1000);
                --ticket;
                cout << td->_name << " : " << ticket << endl;
            }
        }
    }
    delete td;
    return nullptr;
}

int main()
{
    vector<pthread_t> tid(5);
    int cnt = 0;
    pthread_spinlock_t mutex;
    pthread_spin_init(&mutex, PTHREAD_PROCESS_PRIVATE);
    for(auto& e : tid)
    {
        threadDate* td = new threadDate("thread ", &mutex);
        ++cnt;
        td->_name += to_string(cnt);
        int n = pthread_create(&e, nullptr, getTicket, td);
    }


    //等待线程
    for(auto& e : tid)
    {
        pthread_join(e, nullptr);
    }
    //销毁锁
    pthread_spin_destroy(&mutex);

    return 0;
}

但如果临界区中有IO,就不要使用自旋锁。

读写锁

在编写多线程的时候,有一种情况是十分常见的。那就是,有些公共数据修改的机会比较少。相比较改写,它们读的 机会反而高的多。通常而言,在读的过程中,往往伴随着查找的操作,中间耗时很长。给这种代码段加锁,会极大地 降低我们程序的效率。那么有没有一种方法,可以专门处理这种多读少写的情况呢? 有,那就是读写锁。

写者之间是互斥关系

读者之间没有关系

读者和写者之间是互斥且同步的关系

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/460978.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

金融贷款行业如何高效获客,积累意向客户群体——运营商大数据

现如今贷款行业面对的运营压力日益扩大&#xff0c;顾客贮备是生存的关键&#xff0c;传统式的陌生拜访&#xff0c;一切随缘销售市场已不能满足其要求。互联网消费行为的融合与转变是在销售市场端反映&#xff0c;直接影响着广告推广广告策略的确立与运用。 可是&#xff0c;…

移除元素【数组】

⭐前言⭐ ※※※大家好&#xff01;我是同学〖森〗&#xff0c;一名计算机爱好者&#xff0c;今天让我们进入练习模式。若有错误&#xff0c;请多多指教。更多有趣的代码请移步Gitee &#x1f44d; 点赞 ⭐ 收藏 &#x1f4dd;留言 都是我创作的最大的动力&#xff01; 题目 27…

IPEmotion 2023 R1支持在线能量分析

新发布的IPEmotion 2023 R1提供了许多新功能&#xff0c;其中最重要的是新的“在线功率计算&#xff08;Online Power Calculation&#xff09;”功能。该功能允许使用预定义的功率计算来进行测量任务和数据分析。此外&#xff0c;IPEmotion 2023 R1现在支持一种新的存储模式&a…

Maya英文界面怎么改为中文界面

Maya是一款3D动画和视觉效果软件&#xff0c;用于创建逼真的角色和大片般的效果&#xff0c;也是受到电影、电视和游戏行业的 3D 建模师、动画师、照明艺术家和 VFX 艺术家等多数人喜爱的一款3D软件。我们在使用Maya的过程中&#xff0c;常常会遇到一些小阻碍&#xff0c;比如M…

【Python爬虫实战】你不必到处找数据,你完全可以自己爬之Python批量采集图虫网摄影师高清美照,听说~你喜欢御姐...(爬图神器)

前言 怎么批量保存网页图片&#xff1f; 有时候在网页中看到很多美图其中有很多自己喜欢的图片素材或壁纸&#xff0c;一张纸一张下载保存未 免太低效了。 所有文章完整的素材源码都在&#x1f447;&#x1f447; 粉丝白嫖源码福利&#xff0c;请移步至CSDN社区或文末公众ha…

C++哈希应用——位图布隆过滤器

C布隆过滤器 文章目录 C布隆过滤器概念实质用途控制误判率实现插入和查找布隆过滤器的删除 布隆过滤器优点布隆过滤器缺陷相关大数据题目 用哈希表存储用户记录&#xff0c;缺点是需要消耗较大的内存&#xff1b;用位图存储用户记录&#xff0c;缺点是位图一般处理整形&#xf…

P1039 [NOIP2003 提高组] 侦探推理

题目描述 明明同学最近迷上了侦探漫画《柯南》并沉醉于推理游戏之中&#xff0c;于是他召集了一群同学玩推理游戏。游戏的内容是这样的&#xff0c;明明的同学们先商量好由其中的一个人充当罪犯&#xff08;在明明不知情的情况下&#xff09;&#xff0c;明明的任务就是找出这…

Java-设计模式中事件与委托Java版本

目录 背景介绍 实现过程 类图 NS图 代码 客户端 业务封装类 委托类 事件类 猫类 老鼠类 运行结果 总结提升 背景介绍 相信大家在学习大话设计模式的时候都有接触过事件与委托&#xff0c;但是对于事件与委托具体的业务逻辑也不是很清楚&#xff0c;只能照猫画虎去使用…

SEO机制算是让我玩明白了

获取当前时间时间戳&#xff0c;返回遵循ISO 8601扩展格式的日期 new Date(Date.now()).toISOString() 使用moment库转换回来 this.moment(new Date(Date.now()).toISOString()).format("YYYY-MM-DD") js去掉富文本中html标签和图片 filterHtmlTag(val) {if(!val){…

Shell编程规范与使用

一、Shell脚本概述 1&#xff09;Shell的作用——命令解释器&#xff0c;“翻译官” Linux 系统中的 Shell 是一个特殊的应用程序&#xff0c;它介于操作系统内核与用户之间&#xff0c;充当 了一个“命令解释器”的角色&#xff0c;负责接收用户输入的操作指令&#xff08;命…

接口协作--apipost接口协作工具

接口协作 apipost支持接口在线协作编辑功能&#xff0c;打开apipost创业一个团队&#xff0c;在创建一个项目。 在把需要一起协作的人员添加到团队中 在进行项目编辑把需要进行协作的人员拉取到项目中 之后在进入项目创建接口就可以进行接口协作了

scratch猫捉老鼠 少儿编程 电子学会图形化编程scratch编程等级考试二级真题和答案解析2023年3月

目录 scratch猫捉老鼠 一、题目要求 1、准备工作 2、功能实现 二、案例分析

kafka调试脚本的使用

创建名称为test的topic且副本数量3&#xff0c;partition数量6 /etc/kafka/kafka/bin/kafka-topics.sh --create --bootstrap-server 10.1.60.112:9092 --replication-factor 3 --partitions 6 --topic test 查看名称为test的topic信息 /etc/kafka/kafka/bin/kafka-topics.sh -…

uniapp微信小程序图片预览PreviewImage

一、说明 功能&#xff1a;点击图片预览大图&#xff0c;并且可以通过滑动查看不同图片的预览大图。 点击预览大图后&#xff1a; 二、上代码 参考uniapp官方文档 其提供了预览大图的函数uni.previewImage(OBJECT). //放大查看推荐图片enlargePicture(index) {console.log…

【Unity-ML】Unity机器学习(一)

安装环境&#xff1a;Windows10 Anaconda3(64-bit)&#xff0c;网上很多教程&#xff0c;例如这个anaconda下载及安装(保姆级教程) - 知乎anaconda包管理器和环境管理器&#xff0c;强烈建议食用 1.下载官网下载太慢可选用镜像下载 官网下载&#xff1a; Anaconda | Individua…

Softing FiberXpert 700光纤测试套件助力一级多模和单模光纤认证

FiberXpert 700是用于多模和单模的四路波长测试套件&#xff0c;不仅可以对光纤链路进行直观、灵活和快速地认证&#xff0c;而且可以导出数据报告。 测试网络安装以确保其符合指定标准的过程称为认证&#xff0c;并且这通常需要纸质文件作为符合标准的证明。而FiberXpert 700光…

Docker 的数据管理

一、Docker 的数据管理 管理 Docker 容器中数据主要有两种方式&#xff1a;数据卷&#xff08;Data Volumes&#xff09;和数据卷容器&#xff08;DataVolumes Containers&#xff09;。 1&#xff0e;数据卷 数据卷是一个供容器使用的特殊目录&#xff0c;位于容器中。可将宿…

为什么说网络安全行业是IT的风口行业?

前言 2023年网络安全行业的前景看起来非常乐观。根据当前的趋势和发展&#xff0c;一些趋势和发展可能对2023年网络安全行业产生影响&#xff1a; 5G技术的广泛应用&#xff1a;5G技术的普及将会使互联网的速度更快&#xff0c;同时也将带来更多的网络威胁和安全挑战。网络安全…

eBPF技术介绍

前言 eBPF起源于linux内核&#xff0c;它可以以砂箱程序运行在操作系统内核的特权上下文&#xff0c;高效&#xff0c;安全&#xff0c;易于扩展而不需要修改内核源码或者加载内核模块。 操作系统一直是实现观测&#xff0c;安全和网络功能的最理想的地方&#xff0c;因为内核的…

Vue基本的内置指令

前言 除了常见的v-bind,v-for,v-if,v-on.v-model等&#xff0c;本次学习一些vue提供的其他内置指令 1 v-text 给标签插入文本&#xff0c;类似于插值语法 它会把全部的字符串当成文本去解析,不会当成标签的,哪怕写的是标签结构 效果和插值语法是一样的 插值语法比v-text更加…