【Linux 多线程互斥】如何保证锁的原子性(互斥的原理)

news2024/11/17 5:52:39
  1. 临界资源:可以被多个执行流(线程或者叫轻量级进程)同是访问的(多个执行流共享的,比如:全局、堆等等);
  2. 临界区:访问这些临界资源的代码;
  3. 原子性:没有中间态,不做或者做完;

1.展示没有互斥的程序 

1.1.一个购票系统,有5个线程在购票

#include<iostream>
#include<cstdio>
#include<unistd.h>
#include<pthread.h>

int tickets=100;
void* thread_run(void* args)
{
    int tmp=*((int*)args);
    while(1)
    {
        if(tickets>0)//购表
        {
            usleep(10000);
            tickets--;
            printf("我是%d线程,还剩%d\n",tmp,tickets);
        }
        else
        {
            printf("没票了\n");
            break;
        }
    }
    return (void*)0;
}
int main()
{
    pthread_t tid[5];
    for(int i=0;i<5;i++)//创建5个线程
    {
        int* t=new int(i);
        pthread_create(tid+i,NULL,thread_run,(void*)t);
    }
    for(int i=0;i<5;i++)
    {
        pthread_join(tid[i],NULL);
    }
    return 0;
}

执行结果:不是每次都会产生这样的结果 ,把票购成负数了不合理

 原理:

 2.互斥

互斥整个过程:保持临界资源的原子性

pthread_mutex_t lock;//锁

pthread_mutex_init(&lock,NULL);//初始化

pthread_mutex_lock(&lock);//加锁

//临界区

pthread_mutex_unlock(&lock);//解锁

pthread_mutex_destroy(&lock);//删除锁

 修改上面代码

#include<iostream>
#include<cstdio>
#include<unistd.h>
#include<pthread.h>

pthread_mutex_t lk;//锁
int tickets=100;
void* thread_run(void* args)
{
    int tmp=*((int*)args);
    while(1)
    {
        pthread_mutex_lock(&lk);//加锁
        if(tickets>0)
        {
            usleep(10000);
            tickets--;
            printf("我是%d线程,还剩%d\n",tmp,tickets);
        }
        else
        {
            printf("没票了\n");
            pthread_mutex_unlock(&lk);//解锁
            break;
        }
        pthread_mutex_unlock(&lk);//解锁
    }
    return (void*)0;
}
int main()
{
    pthread_mutex_init(&lk,NULL);//初始化
    pthread_t tid[5];
    for(int i=0;i<5;i++)
    {
        int* t=new int(i);
        pthread_create(tid+i,NULL,thread_run,(void*)t);
    }
    for(int i=0;i<5;i++)
    {
        pthread_join(tid[i],NULL);
    }
    pthread_mutex_destroy(&lk);//删除锁
    return 0;
}

3.如何保证锁的原子性(互斥的原理)

为了实现互斥锁操作,大多数体系结构都提供了swap或exchange指令(汇编):作用是把寄存器和内存单元的数据相交换

过程:每一个线程调用lock,会先把自己上下文中关于锁的变量设为0,然后和使用一行代码(原子性)交换上下文的数据和锁的数据,锁的数据被换走变成0,其它线程来交换还是0,会挂起等待循环这个过程,直到换走数据的线程解锁为止;

 如果交换走锁数据的线程时间片到了,被调度那么它也是抱着锁走的,其他线程还是不能执行临界资源

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

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

相关文章

vue动画

vue动画 1.vue动画&#xff08;transition &#xff09; 使用 组件 组件可以用来添加过渡效果&#xff0c;当一个元素或组件被插入或删除时&#xff0c;它会自动应用过渡效果。 name 属性用于指定具体是那个动画生效&#xff0c;如果不加默认是v-开头的 <!-- 可以添加指定的…

Win10搭建Pyspark2.4.4+Pycharm开发环境(亲测可用)

下载资源hadoop3.0.0spark-2.4.4-bin-without-hadoopwinutils下载(对应hadoop3.0.1的bin目录覆盖本地hadoop的bin目录)jdk1.8(默认已按照配置)conda/anaconda(默认已安装)注意:cdh6.3.2的spark为2.4.0但是使用2.4.0本地pyspark有bug,下载的文件可能在第一次解压缩后,如未出现目…

【数据结构】平衡二叉树

目录 一、平衡二叉树的介绍 二、平衡二叉树的插入 1、平衡二叉树的插入步骤 2、平衡二叉树的旋转 2.1左单旋 2.2右单旋 2.3左右双旋 2.4右左双旋 三、平衡二叉树的删除&#xff08;略&#xff09; 四、个人对平衡二叉树见解 五、平衡二叉树整体代码 一、平衡二叉树的…

mycobot 使用教程

(1) 树莓派4B ubuntu系统调整swap空间与使SD卡快速扩容参考&#xff1a;https://www.bilibili.com/read/cv14825069https://blog.csdn.net/weixin_45824920/article/details/114381292?spm1001.2101.3001.6650.1&utm_mediumdistribute.pc_relevant.none-task-blog-2%7Edef…

内推|香港外企急招ETL工程师!数据分析师+Python开发+运营专家

2月已过半还在找工作&#xff1f;快来看看有没有适合你的岗位&#xff01;01公司&#xff1a;友邦科技 工作地点&#xff1a;成都市高新区OCG国际中心招聘岗位&#xff1a;ETL工程师 15-18k该岗位为香港项目&#xff0c;需要有数仓或者大数据经验。本科IT或数据相关专业&#…

深度优先搜索(DFS)-蓝桥杯

一、搜索搜索是“暴力法”算法思想的具体实现。搜索是“通用”的方法。一个问题&#xff0c;如果比较难&#xff0c;那么先尝试一下搜索&#xff0c;或许能启发出更好的算法。技巧:竞赛时遇到不会的难题&#xff0c;用搜索提交一下&#xff0c;说不定部分判题数据很弱&#xff…

8 Flutter UI 之 路由

一 基本路由路由就是页面的跳转&#xff0c;通过Navigator组件管理路由导航Flutter 提供了两种方式 基本路由和命名路由Container(child: Center(child: Column(children: [ElevatedButton(onPressed: () {// 跳转到购物车界面Navigator.of(context).push(MaterialPageRoute(bu…

教你快速学会画动漫人物表情

动漫人物表情画法&#xff0c;3分钟教你快速学会画表情&#xff0c;快来跟我一起零成本学板绘吧&#xff01;咱们的免费板绘系列教程又来啦&#xff0c;今天教大家的板绘技能是什么呢&#xff1f;今天的板绘学习教程来教你如何画动漫女生的表情&#xff01; 板绘动漫女生的表情…

Instruction Tuning:无/少样本学习新范式

作者 | 太子长琴 整理 | NewBeeNLP大家好&#xff0c;这里是NewBeeNLP。今天分享一种简单的方法来提升语言模型的 Zero-Shot 能力——指示&#xff08;或指令&#xff09;微调&#xff08;instruction tuning&#xff09; &#xff0c;在一组通过指示描述的数据集上对语言模型微…

Nodejs和JavaScript的区别

ECMAScript 定义了语法&#xff0c;写javascript和nodejs都必须要遵守变量定义&#xff0c;循环、判断、函数原型和原型链、作用域和闭包、异步 可以看阮一峰老师写的ECMAScript 6 入门 即&#xff1a; 不能操作DOM,不能监听click事件&#xff0c;不能发送ajax请求不能处理…

Java LockSupport学习

面试题: 1、LockSupport为什么可以先唤醒线程后阻塞线程? 因为unpark()获得了一个凭证&#xff0c;之后再调用park()方法&#xff0c;就可以名正言顺的消费凭证&#xff0c;故不会阻塞。 2、LockSupport为什么唤醒两次后阻塞两次&#xff0c;但最终结果还会阻塞线程? 因为凭证…

Android 实现沉浸式全屏

前言 本文总结 Android 实现沉浸式全屏的实现方式。 实现沉浸式全屏 在一些需要全屏显示的场景下,比如玩游戏、看横屏视频的时候,内容全屏,占满窗口的体验会让用户更加沉浸到对内容的消费中,带来好的用户体验。 沉浸式显示具体来说就是如状态栏和导航栏部分的显示效果调…

C#:Krypton控件使用方法详解(第五讲) ——kryptonPanel

今天介绍的Krypton控件中的kryptonPanel&#xff0c;下面开始介绍这个控件的属性&#xff1a;首先要介绍的是这个控件的外观属性&#xff1a;Cursor属性&#xff1a;表示鼠标移动过这个控件的时候&#xff0c;鼠标的显示状态。具体属性值有哪些&#xff0c;如下图所示&#xff…

第一批因ChatGPT坐牢的人,已经上路了

大家好&#xff0c;我是 Jack。 ChatGPT 的火爆有目共睹&#xff0c;有人靠着它赚了第一桶金&#xff0c;也有人靠着它即将吃上第一顿牢饭。 任何一件东西的火爆&#xff0c;总会给一些聪明人带来机会。 艾尔登法环火的时候&#xff0c;一堆淘宝卖魂的&#xff1b;羊了个羊火…

动漫人物眼睛画法

本期的动漫绘画课程教大家来学习动漫人物眼睛画法&#xff0c;结合板绘软件从草稿开始一步步教你画出动漫人物眼睛&#xff0c;不用报动漫培训班也能学会&#xff0c;快来跟着本期的动漫人物眼睛画法教程试试吧&#xff01; 动漫人物眼睛画法步骤教程&#xff1a; 注意&#x…

Linux内核实现完全公平调度算法

Linux 进程调度算法经历了以下几个版本的发展&#xff1a; 基于时间片轮询调度算法。(2.6之前的版本)O(1) 调度算法。(2.6.23之前的版本)完全公平调度算法。(2.6.23以及之后的版本) 完全公平调度算法基本原理 完全公平调度算法 体现在对待每个进程都是公平的&#xff0c;那么…

ChatGPT AI 人工智能 开发路径

ChatGPT&#xff08;全名&#xff1a;Chat Generative Pre-trained Transformer&#xff09;&#xff0c;美国OpenAI研发的聊天机器人程序&#xff0c;于2022年11月30日发布。 推荐以下几个AI 开发学习资源 一、GPTZero AI: GPTZero GPTZero 是普林斯顿大学学生 Edward Tian …

Java爬虫—WebMagic

一&#xff0c;WebMagic介绍WebMagic企业开发&#xff0c;比HttpClient和JSoup更方便一&#xff09;&#xff0c;WebMagic架构介绍WebMagic有DownLoad&#xff0c;PageProcessor&#xff0c;Schedule&#xff0c;Pipeline四大组件&#xff0c;并有Spider将他们组织起来&#xf…

MySQL中JSON数据类型详解

目录 概要及优点 JSON定义 JSON字段的增删改查操作 插入操作 查询操作 修改操作 删除操作 如何对JSON字段创建索引&#xff1f; 加索引查询结果分析&#xff1a; 不加索引查询结果分析&#xff1a; 使用JSON时的注意事项 概要及优点 JSON数据类型是MySQL5.7.8开始支持的…

FlowChartX/Diagramming for ActiveX 4.9.8 Crack

构建完美的图表 如果您的应用程序以 ActiveX 平台为目标&#xff0c;并且您需要实现图表功能&#xff0c;那么您所需要的只是 FlowChartX。它提供了创建、自定义和呈现流程图的所有功能。 ActiveX 图表库&#xff1a;分类图表 图 Diagramming for ActiveX该组件为您提供了一组…