范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文
国学影视

简单分析Linux信号量机制

  说明:Kernel版本:4.14 ARM64处理器,Contex-A53,双核 使用工具:Source Insight 3.5, Visio 1. 概述信号量 semaphore ,是操作系统中一种常用的同步与互斥的机制;信号量允许多个进程(计数值>1)同时进入临界区; 如果信号量的计数值为1,一次只允许一个进程进入临界区,这种信号量叫二值信号量; 信号量可能会引起进程睡眠,开销较大,适用于保护较长的临界区; 与读写自旋锁类似,linux内核也提供了读写信号量的机制;
  本文将分析信号量与读写信号量的机制,开始吧。 2. 信号量2.1 流程分析可以将信号量比喻成一个盒子,初始化时在盒子里放入N把钥匙,钥匙先到先得,当N把钥匙都被拿走完后,再来拿钥匙的人就需要等待了,只有等到有人将钥匙归还了,等待的人才能拿到钥匙;
  信号量的实现很简单,先看一下数据结构: struct semaphore { 	raw_spinlock_t		lock;       //自旋锁,用于count值的互斥访问 	unsigned int		count;      //计数值,能同时允许访问的数量,也就是上文中的N把锁 	struct list_head	wait_list;      //不能立即获取到信号量的访问者,都会加入到等待列表中 };   struct semaphore_waiter { 	struct list_head list;      //用于添加到信号量的等待列表中 	struct task_struct *task;   //用于指向等待的进程,在实际实现中,指向current 	bool up;                    //用于标识是否已经释放 };
  流程如下:
  down 接口用于获取信号量,up 用于释放信号量;调用 down 时,如果sem->count > 0 时,也就是盒子里边还有多余的锁,直接自减并返回了,当sem->count == 0 时,表明盒子里边的锁被用完了,当前任务会加入信号量的等待列表中,设置进程的状态,并调用schedule_timeout 来睡眠指定时间,实际上这个时间设置的无限等待,也就是只能等着被唤醒,当前任务才能继续运行;调用 up 时,如果等待列表为空,表明没有多余的任务在等待信号量,直接将sem->count 自加即可。如果等待列表非空,表明有任务正在等待信号量,那就需要对等待列表中的第一个任务(等待时间最长)进行唤醒操作,并从等待列表中将需要被唤醒的任务进行删除操作;
  更多linux内核视频教程文档资料免费领取后台私信【内核】自行获取.
  2.2 信号量缺点对比下 《Linux Mutex机制分析》 说过的Mutex ,Semaphore 与Mutex 在实现上有一个重大的区别:ownership 。Mutex 被持有后有一个明确的owner ,而Semaphore 并没有owner ,当一个进程阻塞在某个信号量上时,它没法知道自己阻塞在哪个进程(线程)之上;没有 ownership 会带来以下几个问题:在保护临界区的时候,无法进行优先级反转的处理; 系统无法对其进行跟踪断言处理,比如死锁检测等; 信号量的调试变得更加麻烦;
  因此,在 Mutex 能满足要求的情况下,优先使用Mutex 。2.3 其他接口
  信号量提供了多种不同的信号量获取的接口,介绍如下: /* 未获取信号量时,进程轻度睡眠:TASK_INTERRUPTIBLE */ int down_interruptible(struct semaphore *sem) /* 未获取到信号量时,进程中度睡眠:TASK_KILLABLE */ int down_killable(struct semaphore *sem) /* 非等待的方式去获取信号量 */ int down_trylock(struct semaphore *sem) /* 获取信号量,并指定等待时间 */ int down_timeout(struct semaphore *sem, long timeout)3. 读写信号量
  《linux spinlock/rwlock/seqlock原理剖析(基于ARM64)》 文章中,我们分析过读写自旋锁,读写信号量的功能类似,它能有效提高并发性,我们先明确下它的特点:允许多个读者同时进入临界区; 读者与写者不能同时进入临界区(读者与写者互斥); 写者与写者不能同时进入临界区(写者与写者互斥); 3.1 数据结构
  读写信号量的数据结构与信号量的结构比较相似: struct rw_semaphore { 	atomic_long_t count;        //用于表示读写信号量的计数 	struct list_head wait_list;     //等待列表,用于管理在该信号量上睡眠的任务 	raw_spinlock_t wait_lock;   //锁,用于保护count值的操作 #ifdef CONFIG_RWSEM_SPIN_ON_OWNER 	struct optimistic_spin_queue osq; /* spinner MCS lock */    //MCS锁,参考上一篇文章Mutex中的介绍 	/* 	 * Write owner. Used as a speculative check to see 	 * if the owner is running on the cpu. 	 */ 	struct task_struct *owner;      //当写者成功获取锁时,owner会指向锁的持有者 #endif #ifdef CONFIG_DEBUG_LOCK_ALLOC 	struct lockdep_map	dep_map; #endif };最关键的需要看一下 count 字段,掌握了这个字段的处理,才能比较好理解读写信号量的机制;《inux spinlock/rwlock/seqlock原理剖析(基于ARM64)》 文章中提到过读写自旋锁,读写自旋锁中的lock 字段,bit[31]用于写锁的标记,bit[30:0]用于读锁的统计,而读写信号量的count 字段也大体类似;
  以32位的count值为例,高16bit代表的是 waiting part ,低16bit代表的是active part ;RWSEM_UNLOCKED_VALUE :值为0,表示锁未被持有,没有读者也没有写者;RWSEM_ACTIVE_BIAS :值为1,,该值用于定义RWSEM_ACTIVE_READ_BIAS 和RWSEM_ACTIVE_WRITE_BIAS ;RWSEM_WAITING_BIAS :值为-65536,当有任务需要加入到等待列表中时,count值需要加RWSEM_WAITING_BIAS ,有任务需要从等待列表中移除时,count值需要减去RWSEM_WAITING_BIAS ;RWSEM_ACTIVE_READ_BIAS :值为1,当有读者去获取锁的时候,count值将加RWSEM_ACTIVE_READ_BIAS ,释放锁的时候,count值将减去RWSEM_ACTIVE_READ_BIAS ;RWSEM_ACTIVE_WRITE_BIAS ,值为-65535,当有写者去获取锁的时候,count值将加RWSEM_ACTIVE_WRITE_BIAS ,释放锁的时候,count值需要减去RWSEM_ACTIVE_WRITE_BIAS ;
  在获取释放读锁和写锁的全过程中, count 值伴随着上述这几个宏定义的加减操作,用于标识不同的状态,可以罗列如下:0x0000000X :活跃的读者和正在申请读锁的读者总共为X 个,没有写者来干扰;0x00000000 :没有读者和写者来操作,初始化状态;0xFFFF000X :分为以下几种情况:0xFFFF000X = RWSEM_WAITING_BIAS + X * RWSEM_ACTIVE_READ_BIAS ,表示活跃的读者和正在申请读锁的读者总共有X 个,并且还有一个写者在睡眠等待;0xFFFF000X = RWSEM_ACTIVE_WRITE_BIAS + (X - 1)* RWSEM_ACTIVE_READ_BIAS ,表示有一个写者在尝试获取锁,活跃的读者和正在申请读锁的读者总共有X-1 个;0xFFFF0001 :分为以下几种情况:0xFFFF0001 = RWSEM_ACTIVE_WRITE_BIAS ,有一个活跃的写者,或者写者正在尝试获取锁,没有读者干扰;0xFFFF0001 = RWSEM_ACTIVE_READ_BIAS + RWSEM_WAITING_BIAS ,有个写者正在睡眠等待,还有一个活跃或尝试获取锁的读者;3.1 读信号量3.1.1 读者获取锁
  特点:读者与读者可以并发执行,读者与写者互斥执行,因此当有写者持有锁的时候,读者将进入睡眠状态; 当 sem->count 加1后还是小于0,代表锁已经被写者持有了,读者获取锁失败,进入rwsem_down_read_failed 函数;如果 sem->wait_list 是空时,代表没有任务在等待列表中,首次加入时,sem->count 值需要加上RWSEM_WAITING_BIAS ,表示有任务在等待列表中;如果此时 sem->count == RWSEM_WAITING_BIAS 或者count > RWSEM_WAITING_BIAS && adjustment != RWSEM_ACTIVE_READ_BIAS ,表示此时写者将锁释放了,因此需要去唤醒在等待列表中的任务;如果写者没有释放锁,那就进入循环,并调用 schedule 让出CPU,直到锁被释放了,那么从代码流程中看,只有!waiter.task 时才会跳出循环,也就是waiter.task == NULL 时,才是获取成功,这个操作是在__rwsem_mark_wake 中通过smp_store_release(&waiter->task, NULL) 实现的;在等待获取锁的循环中,需要对信号进行处理,如果对应的等待任务没被唤醒,那么直接跳转到 out_nolock 处,接下来的处理就是一些逆操作了,包括从等待列表中删除,如果是等待列表中的首个任务,还需要减去RWSEM_WAITING_BIAS 等;
  总结一下: 读者获取锁的时候,如果没有写者持有,那就可以支持多个读者直接获取;而如果此时写者持有了锁,读者获取失败,它将把自己添加到等待列表中,(这个等待列表中可能已经存放了其他来获取锁的读者或者写者),在将读者真正睡眠等待前,还会再一次判断此时是否有写者释放了该锁,释放了的话,那就需要对睡眠等待在该锁的任务进行唤醒操作了 3.1.2 读者释放锁
  释放锁的时候 sem->count 值进行减1操作;减1操作之后得到的 count 值小于-1,并且active part 是全零,代表等待列表中有写任务在睡眠等待,因此需要进行唤醒操作;唤醒操作中,如果有自旋等待的任务,那就可以直接返回了,毕竟人家在自旋呢,又没有睡眠; 没有自旋等待任务,那就去唤醒等待列表中的任务了; 3.2 写信号量3.2.1 写者获取锁
  写者的特点:看谁都不顺眼,跟谁都互斥,有我没你。只要有一个写者在持有锁,其他的读者与写者都无法获取; 在写者获取锁的时候,将 sem->count 值加上RWSEM_ACTIVE_WRITE_BIAS ,如果这个值不等于RWSEM_ACTIVE_WRITE_BIAS ,表示有其他的读者或写者持有锁,因此获取锁失败,调用rwsem_down_write_failed 来处理;调用 rwsem_optimistic_spin 进行乐观自旋去尝试获取锁,获取了的话,则直接返回,optimistic spin 可以参考《Linux Mutex机制分析》 文章中的分析,它的作用也是性能的优化,认为锁的持有者会很快释放,因此当前进程选择自旋而不是让出CPU,减少上下文切换带来的开销;如果等待列表中有读者任务在睡眠等待,此时假如写者释放了锁,那么需要先将读者任务都给唤醒了;如果等待列表中没有任务,也就意味着当前的写者是第一个任务,因此将 sem->count 值加上RWSEM_WAITING_BIAS ;循环等待获取锁,这个过程与 down_read 是类似的;
  总结 写者获取锁时,只要锁被其他读者或者写者持有了,则获取锁失败,然后进行失败情况处理。在失败情况下,它本身会尝试进行optimistic spin去尝试获取锁,如果获取成功了,那就是皆大欢喜了,否则还是需要进入慢速路径。慢速路径中去判断等待列表中是否有任务在睡眠等待,并且会再次尝试去查看是否已经有写者释放了锁,写者释放了锁,并且只有读者在睡眠等待,那么此时应该优先让这些先等待的任务唤醒 3.2.2 写者释放锁
  写者释放锁的时候,有一个关键的操作,将 sem->owner 进行清零操作,在写者获取锁的时候会将该值设置成持有锁的进程;释放锁的时候,需要减去 RWSEM_ACTIVE_WRITE_BIAS ,然后再去判断值,如果此时还有任务在睡眠等待,那就进行唤醒操作;3.3 总结
  理解读写信号量有几个关键点: 读写信号量的特性可以与读写自旋锁进行类比(读者与读者并发、读者与写者互斥、写者与写者互斥),区别在于读写信号量可能会发生睡眠,进而带来进程切换的开销; 为了优化读写信号量的性能,引入了 MCS锁 机制,进一步减少切换开销。第一个写者获取了锁后,第二个写者去获取时自旋等待,而读者去获取时则会进入睡眠;读写信号量的 count 值很关键,代表着读写信号量不同状态的切换,因此也决定了执行流程;读者或写者释放锁的时候,去唤醒等待列表中的任务,需要分情况处理。等待列表中可能存放的是读者与写者的组合,如果第一个任务是写者,则直接唤醒该写者,否则将唤醒排在前边的连续几个读者;
  首页 - 内核技术中文网 - 构建全国最权威的内核技术交流分享论坛
  转载地址:深入分析Linux信号量机制 - 圈点 - 内核技术中文网 - 构建全国最权威的内核技术交流分享论坛

有胃病的人可以吃馒头吗?其实真正不能吃的是这5种食物如今,胃部疾病的患者越来越多,正在呈逐年上升的趋势发展,大部分诱发的人群为2540岁的成年女性。正所谓10人9胃,根据胃病防治指南数据最新统计我国胃病的患发率高达86。3,综合人数外媒梅德韦杰夫称应该在顿巴斯举行公投据塔斯社莫斯科9月20日报道,俄罗斯联邦安全会议副主席德米特里梅德韦杰夫表示,有必要在顿涅茨克和卢甘斯克举行加入俄罗斯的全民公投。梅德韦杰夫在电报社交平台发文称全民公投不仅对于系统粮食干燥机价格多少钱一台?粮食干燥机要怎么挑选?当下秋粮采收季节,同时也伴随着秋雨绵绵的天气,如果不能及时地将这些粮食水分降到安全水分的范围,会对粮食造成非常大的损失。而解决方法也很简单,一台粮食干燥机就能全部搞定。那么粮食干燥重罚3660万!这家A股实控人被十年市场禁入中国基金报记者颜颖债券违约近四年后,曾经红极一时的知名日化企业迎来了监管调查结果。早在2021年1月,因涉嫌债券欺诈发行及信披违法,洛娃集团被证监会立案调查。日前,洛娃集团披露公告中兴通讯最新公告监事李妙娜的母亲短线交易及致歉中兴通讯公告,2022年9月20日,公司收到公司监事李妙娜出具的关于本人亲属买卖中兴通讯股票构成短线交易的情况说明及致歉,获悉李妙娜的母亲李如香于2022年9月14日至2022年9马克吐温自传妈妈艰苦的一生我妈妈是在一八九年十月的时候去世的,那年她八十八岁,真是高龄。她的一生,可真是艰苦奋斗的一生,因为四十岁的时候,她的身体便已经很虚弱了,被认为患上了不治之症,不久于人世了。二十五岁持续成长之路凯茜妈妈的涅槃重生你有没有设想过你的未来会如何度过?我在体制内工作近40年,沉溺于这种安逸的舒适区,得过且过,习惯接受符合自己世界观的东西,做一天和尚撞一天钟,在退休前的若干年更是如此。退休后更是浑花钱如流水的7位女星再有钱也养不起,她们的消费高到你想不到文闲撰奇侠编辑闲撰奇侠王传君曾经在一次采访中表示,自己在最穷的时候,卡里只剩下一百万,这让他感到非常焦虑。这就是娱乐圈的现状,当明星还在为自己只剩几百万发愁时,许多普通家庭可能一辈ampampquot红极一时ampampquot的9个组合,理念不合的背后,藏着多少不为人知的龌龊文大牌娱姐娱乐圈一直以来都不乏明星组合,从小虎队到She再到Twins,从羽泉到凤凰传奇再到筷子兄弟,他们几乎都引领了一个时代的音乐潮流。但事物发展的规律不容改变,所谓合久必分,分一生荒唐事,老来牛归群说牛群上不少朋友一直在留言,都很关心牛群,尤其是对牛群的现状十分好奇。看到这么多观众关注相声关心牛群,我是感觉特别欣慰,说明大家还是懂相声,追求真正的相声艺术,没有被现在的三俗相声演员所迷狂傲无知的张铁林,走到了今天这一步该怪谁9月份中旬,电视剧老家伙发布了首支预告,估摸着离正式播出日子也不远了。这部剧主演是张国立,王刚和张铁林。这三人自铁齿铜牙纪晓岚合作,到如今,仍然是不少人心目中的铁三角。先不说新剧如
社零数据大幅下降下半年的经济会好起来吗国家统计局5月16日发布数据显示,1至4月,全国固定资产投资(不含农户)同比增长6。8社会消费品零售总额同比下降0。2货物进出口总额同比增长7。9全国规模以上工业增加值同比增长4。日产奇骏优惠后这样的落地价,大家觉得怎么样?能买吗?大家好!我是小瑶。今天咱们特地抽空来到了日产4S店,主要来看东风日产旗下一款比较受争议的SUV车型,说到这里,可能有部分车友已经猜出来咱们要来看的是哪一款车型了,没错,今天咱们来看国际乒联官宣!最新比赛名单公布,国乒正式报名,迎战张本伊藤北京时间5月19日消息,国际乒联正式公布了6月前两站WTT赛事的运动员名单,其中国乒的8位00后小将已正式报名,即将与张本智和伊藤美诚等人一起出战克罗地亚赛,而世界冠军奥恰洛夫等人海贼王1049话解读如果800年前的乔伊波伊不是路飞,剧情就崩了重新看完海贼王这几期漫画,突然发现了不少的细节问题,最大的问题就是乔伊波伊,根据目前的证据,所有信息都指向,乔伊波伊会出现在和之国,凯多一直相信这个传说,所以他占据了和之国,御田也一夜蒸发3100亿!净利暴降14,沃尔玛的大雷,终于爆了当国美18个月重回应有市场地位变得遥遥无期之际,尚未从闭店风波中缓过神来的沃尔玛再遭一击!刚刚!新鲜出炉的2022年一季报显示,沃尔玛净利润暴降14,受业绩影响,沃尔玛股价创35年只有女儿没生儿子是断后?老了才知道生儿生女的差别有多大大家好,我是践行终身学习的西红柿妈妈!90后的这个群体,大多数都是独生子女,他们的父母60后,在那个时候,以生儿子为荣。想着生了儿子是后继有人,生女儿反而令他们有些遗憾。如今也迎来总喜欢在睡前关灯玩手机的人,不用多久,就会落下6个毛病手机,已经成为了现代人的第三只手,工作时得带着,吃饭时得带着,就连睡觉时都得带着,不然总觉得身体缺少了些什么,而我们看手机的时间,也随着各路APP的研发,而逐渐被拉长,特别是在刷短大腿口语女性bmi越大越好吗?前两天,隔壁桌美女同事给我发消息女性bmi多少比较合适?bmi?bmi是什么?不回答显得我好无知我赶紧去查了一下原来不是我的问题bmi是BodyMassIndex身体质量指数(一种大长脸也好看的12位女星,个个明艳大气,高级感十足脸型并不能决定女生能不能称为美女,当然固定意义上的长脸或者圆脸也不能绝对定义为美或者丑。而是否能称为美女还要看五官是否精致,视觉上是否更精致高级,以下12位女星就是长脸且高级的美女2014年赌王长女何超英去世,曾是父亲掌上明珠,离婚后丧母又丧弟赌王长女孤独下葬2014年,澳门赌王何鸿燊的长女何超英因病去世。在外人看来,出身顶级豪门的她,死后理应得到厚葬。然而令人惊讶的是,这场葬礼办得极为凄凉。父亲何鸿燊对外宣称不想感受白演员王耀庆为了不搬家娶了房东女儿,婚后生两子,幸福美满大家都知道王耀庆是霸总人设。霸总背后怎么可以少了一个小娇妻呢?而王耀庆背后的小娇妻就是郭晏青。对于郭晏青这个名字,大家都不是很熟悉。不过王耀庆却很熟悉,因为两人在小学四年级就认识了