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

XV6——锁与并发

在操作系统中,什么情况下会导致并发?

  • 多线程
  • 多处理器
  • 中断

Xv6不支持多线程,但其他两种情况确实会在Xv6中发生。为了解决并发问题,需要一种机制:

Xv6中实现了两种锁:自旋锁睡眠锁

自选锁

// Mutual exclusion lock.
struct spinlock
{uint locked; // Is the lock held?// For debugging:char *name;		 // Name of lock.struct cpu *cpu; // The cpu holding the lock.
};

最核心的字段是locked 

  • 当locked == 0,说明无锁,可以访问
  • 当locked == 1,说明已经上锁,无法访问
加锁
// Acquire the lock.
// Loops (spins) until the lock is acquired.
void acquire(struct spinlock *lk)
{push_off(); // disable interrupts to avoid deadlock.if (holding(lk))panic("acquire");// On RISC-V, sync_lock_test_and_set turns into an atomic swap://   a5 = 1//   s1 = &lk->locked//   amoswap.w.aq a5, a5, (s1)while (__sync_lock_test_and_set(&lk->locked, 1) != 0);// Tell the C compiler and the processor to not move loads or stores// past this point, to ensure that the critical section's memory// references happen strictly after the lock is acquired.// On RISC-V, this emits a fence instruction.__sync_synchronize();// Record info about lock acquisition for holding() and debugging.lk->cpu = mycpu();
}

加锁过程可以拆分为4步:

  1. 关中断
  2. 获取锁
  3. 设置内存屏障
  4. 更新数据
解锁
// Release the lock.
void release(struct spinlock *lk)
{if (!holding(lk))panic("release");lk->cpu = 0;// Tell the C compiler and the CPU to not move loads or stores// past this point, to ensure that all the stores in the critical// section are visible to other CPUs before the lock is released,// and that loads in the critical section occur strictly before// the lock is released.// On RISC-V, this emits a fence instruction.__sync_synchronize();// Release the lock, equivalent to lk->locked = 0.// This code doesn't use a C assignment, since the C standard// implies that an assignment might be implemented with// multiple store instructions.// On RISC-V, sync_lock_release turns into an atomic swap://   s1 = &lk->locked//   amoswap.w zero, zero, (s1)__sync_lock_release(&lk->locked);pop_off();
}

解锁过程与加锁过程相反:

  1. 重置数据
  2. 设置内存屏障
  3. 释放锁
  4. 开中断
关中断
void push_off(void)
{int old = intr_get();intr_off();if (mycpu()->noff == 0)mycpu()->intena = old;mycpu()->noff += 1;
}

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • AI技术在招聘数据分析洞察中的作用
  • haproxy总结与实验
  • sgetrf M N is 103040 时报错,这是个bug么 lapack and Openblas the same,修复备忘
  • 网站证书过期导致WordPress后台无法登录问题解决,页面样式丢失
  • EMQX Platform Snowflake:构建可再生分布式能源的智慧未来
  • 了解LVS,配置LVS
  • 刚刚,模糊测试平台SFuzz受到行业认可
  • 在 SOCKS 和 HTTP 代理之间如何选择?
  • Elasticsearch自动补全功能实践与Java API应用
  • 若依线程池多线程并发 ruoyi-vue SpringBoot 实战批量发送微信小程序订阅消息
  • QT 的 QSettings 读写 INI 文件的示例
  • 前后端分离时代的SEO实践经验
  • facebook广告效果下降,可能是进入了疲劳期
  • 数据洞察力的魔法:自然语言处理在数据分析中的应用
  • ASP.NET Core Web API中实现缓存
  • 【笔记】你不知道的JS读书笔记——Promise
  • 【翻译】babel对TC39装饰器草案的实现
  • Apache Pulsar 2.1 重磅发布
  • CSS 提示工具(Tooltip)
  • fetch 从初识到应用
  • github指令
  • js继承的实现方法
  • js数组之filter
  • JS专题之继承
  • js作用域和this的理解
  • Redis在Web项目中的应用与实践
  • SQL 难点解决:记录的引用
  • vue数据传递--我有特殊的实现技巧
  • webpack项目中使用grunt监听文件变动自动打包编译
  • 从@property说起(二)当我们写下@property (nonatomic, weak) id obj时,我们究竟写了什么...
  • 大快搜索数据爬虫技术实例安装教学篇
  • 对超线程几个不同角度的解释
  • 前端_面试
  • 深度学习在携程攻略社区的应用
  • 使用 Node.js 的 nodemailer 模块发送邮件(支持 QQ、163 等、支持附件)
  • 小白应该如何快速入门阿里云服务器,新手使用ECS的方法 ...
  • !!Dom4j 学习笔记
  • #数据结构 笔记三
  • $ is not function   和JQUERY 命名 冲突的解说 Jquer问题 (
  • (4)Elastix图像配准:3D图像
  • (bean配置类的注解开发)学习Spring的第十三天
  • (pojstep1.1.2)2654(直叙式模拟)
  • (Redis使用系列) Springboot 使用redis实现接口幂等性拦截 十一
  • (附源码)springboot家庭财务分析系统 毕业设计641323
  • (附源码)springboot炼糖厂地磅全自动控制系统 毕业设计 341357
  • (面试必看!)锁策略
  • (四)【Jmeter】 JMeter的界面布局与组件概述
  • (四)模仿学习-完成后台管理页面查询
  • (转)清华学霸演讲稿:永远不要说你已经尽力了
  • (转)四层和七层负载均衡的区别
  • (转载)利用webkit抓取动态网页和链接
  • *1 计算机基础和操作系统基础及几大协议
  • ./configure,make,make install的作用
  • .NET Core WebAPI中使用swagger版本控制,添加注释
  • .NET Core 版本不支持的问题