当前位置: 首页 > news >正文

Linux:互斥

目录

一、互斥概念

二、互斥的使用函数

三、互斥的底层原理


一、互斥概念

        互斥,全称是线程互斥,互斥是一套解决方案,用来保护临界资源。一般在多线程的代码中,要使用互斥这套解决方案来保护临界资源。

        主要从代码的角度理解互斥,下面的代码背景:多线程代码,有4个线程在其函数中访问了临界资源,现在用互斥来保护临界资源。

二、互斥的使用函数

man pthread_mutex_init

   

        pthread_mutex_t 等于定义一把互斥锁。定义互斥锁有两种情况,

  • 如果打算将互斥锁定义成全局或者静态的,则执行这条代码即可。

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

//1.定义全局互斥锁
pthread_mutex_t g_mutex= PTHREAD_MUTEX_INITIALIZER;
void route(ThreadData* td)
{
    while(1)
    {
        pthread_mutex_lock(&g_mutex);
        if(td->_tick>0)
        {
            usleep(1000);
            printf("%s running,can get only tick:%d\n",td->_name.c_str(),td->_tick);
            td->_tick--;
            pthread_mutex_unlock(&g_mutex);
            td->_total++;
        }
        else{
            pthread_mutex_unlock(&g_mutex);

            break;
        }

    }

}
  • 如果打算将互斥锁定义在局部,则需要使用相关接口初始化和销毁。

  • 更优雅的做法,把上锁和解锁做封装,交给类来做。

//3.RAII风格的加锁、解锁
void route(ThreadData* td)
{
    while(1)
    {
        //在循环内创建一个类 临时对象,出循环销毁,调用析构函数,同时解锁
        Lock lock(&td->_mutex);
        if(td->_tick>0)
        {
            usleep(1000);
            printf("%s running,can get only tick:%d\n",td->_name.c_str(),td->_tick);
            td->_tick--;
            td->_total++;
        }
        else{
           
            break;
        }

    }
}

三、互斥的底层原理

  • 为什么互斥锁能解决共享资源被多个线程访问的问题。

1.多线程本质是在并行运行程序,临界资源即共享资源,临界区即访问临界资源的代码,而保护共享资源,其实就是想办法在把临界区的代码变成多线程在串行访问

2.专业来说,就是要求,临界区的代码要具备原子性,即要么还没开始做,要么已经完成。

3.在cpu执行代码的角度来看,要求临界区代码转成汇编后,只需一个时钟周期即可完成。

4.显然,临界区的代码,不可能只是一句汇编。

5.因此,有了互斥锁的设计,只需保证申请锁的过程是原子性的即可,让其他线程卡在申请锁这个语句即可。

  • 底层汇编

        

        上锁的过程,在转成汇编语句后,就是上面这几句汇编语言,其中最重要的一句就是xchgb语句,这个语句就是原子的,交换寄存器和内存中的值,而内存中的这个值代表着锁,寄存器的值却是0。

        这个过程其实是这样的:内存中定义锁后,线程1执行xchgb后,意味着线程1申请到了锁,也意味着线程1 把临界资源上了锁,此时如果发生线程切换,线程2执行xchgb后,因为内存中已经没有了锁这个资源,所以后面的条件语句线程2也就无法执行。

        这就是互斥锁的最底层实现原理。

相关文章:

  • 算法与数据结构(格雷编码)
  • Node.js 中 fs 模块的高级用法
  • 基于 Spring Boot 的高校网上缴费综合务系统设计与实现
  • C# 封装
  • WIFI的SSID超长,隐藏,重复 (2.4G和5G差异)
  • DeepSeek 提示词:基础结构
  • java给钉钉邮箱发送邮件
  • stm32仿真 74hc238流水灯 数码管动态数字显示
  • 快速入门——前端数据模拟MockJS
  • java后端开发day19--学生管理系统升级
  • TypeError: the JSON object must be str, bytes or bytearray, not dict
  • LLM全栈框架完整分类清单(预训练+微调+工具链)
  • VMware中的linux常用指令
  • STM32 缺一不可的最基础的初始化部分
  • CSS—引入方式、选择器、复合选择器、文字控制属性、CSS特性
  • smolagents学习笔记系列(六)Secure code execution
  • Redis 面试题
  • RT-Thread+STM32L475VET6——TF 卡文件系统
  • 创建型模式 - 原型模式 (Prototype Pattern)
  • 【Leetcode】两数之和
  • 以色列总理:以哈谈判内容包括“结束战争的框架”
  • 新华每日电讯:博物馆正以可亲可近替代“高冷范儿”
  • 中国驻美大使:远离故土的子弹库帛书正随民族复兴踏上归途
  • 光明日报社副总编辑薄洁萍调任求是杂志社副总编辑
  • 外企聊营商|上海仲裁:化解跨国企业纠纷的“上海路径”
  • 没有握手,采用翻译:俄乌三年来首次直接会谈成效如何?