死锁
要将线程阻塞住,不继续向下执行有两个方法:一种直接让线程睡觉,不占用CPU资源,CPU不分配时间给这个线程,另一种就是忙等OSSpinLock(自旋锁),等待锁的线程处于忙等(busy-wait)状态,一直占用着CPU资源(一直用while循环判断锁有么有被放开);
自旋锁优先级反转
比如有thread1,thread2,thread3假设开启了3条线程,有可能这三个线程同时执行任务,线程调度(安排时间给线程执行任务),CPU有给3个线程的执行时间比如都是10ms,大家就觉得在同时进行,实现多线程方案.这个就是时间片轮转调度算法,其实操作系统在调度进程和线程都是使用时间片轮转,这里还有线程优先级问题,如果thread1的优先级比较高,那给thread1分配的时间多,或者先让thread1执行.
比如thread1 优先级最高 , thread2 优先级中等,thread3优先级最低
假设thread2先进来发现锁没有加,意味着先把锁锁住,对资源进行处理,紧接着thread1进来,发现锁被别人加过了,所以thread1就会忙等一直判断锁是否被解开,由于thread1的优先级比较高,有可能CPU一直在分配时间给thread1,CPU就没有时间分配给thread2让线程2执行对资源处理的代码,thread2的代码不能继续往下走,就永远放不开这把锁,那么thread3就一直等,就死锁了,
这里如果让线程1不是忙等而是去睡觉的话,就不会占用CPU资源,这样就不会出现死锁现象
优先级反转和解决
优先级反转的描述:
假设任务1,任务2,任务3;他们的优先级顺序分别为1 > 2 > 3。有一个稀缺资源S,S由一个信号量控制为互斥访问。
任务3正在执行,并申请到了资源S;
任务1抢占了任务3的执行,任务3挂起,任务1执行;
任务1申请资源S,发现被占用,所以挂起,任务3恢复执行;
任务2抢占了任务3的执行,任务3挂起,任务2执行;
任务2执行完毕,任务3恢复;
任务3释放资源S,任务1抢占资源S,任务1执行,任务3挂起;
任务1执行完毕,任务3执行。
以上可以看出,任务2虽然比任务1优先级低,但是比任务1优先执行。也就是说任务1的优先级被降低到了任务3的级别。
分析:
由于稀缺资源S的独占性,任务3在申请到资源后,任务1必然会在任务3释放资源后才能执行完成。而任务2肯定会抢占任务3的执行。这个时候,要想任务1比任务2之前执行,有两种方法:任务3释放资源,任务2不能抢占任务3。
任务3释放资源。这条路走不通,因为独占资源没有操作完成就释放,要么回滚,要么出错。(X)
任务2不能抢占任务3。提升任务3的优先级高于任务2就可以了。(V)提高到多少?假如任务1和任务5共抢资源S,那么任务2、3、4都有可能抢去任务5的执行权,所以任务提升一定要和资源S被申请的最高优先级平等或者大于。对于有相同优先级的内核来说,任务5提升到任务1的优先级即可,对于优先级单一的内核,如ucos,就要提升到高一点。
解决方法:
优先级天花板。当任务3使用资源S时,就把任务3的优先级提升到能访问资源S的最高优先级,执行完成释放资源之后,把优先级再改回来;这样的方法,简单易行,解决了多个高优先级任务抢占资源S的问题。但是带来了一些缺点,就是不一定每次都有高优先级任务抢占资源S,每次都提升优先级是对CPU资源的一种浪费。
优先级继承。当任务3使用资源S时,任务1抢占执行权,申请资源S,比较资源1和资源3的优先级,假如任务1优先级高,才提升任务3,提升到和任务1相同的优先级,当任务3释放资源后,将优先级再调整回来。相对于优先级天花板方法,相当于延后执行,克服了任务1的缺点,自己本身的特点是,逻辑复杂,需要操作系统支持相同优先级。在ucos中不容易实现。
两者结合的方案:当任务3使用资源S时,任务1抢占执行权,申请资源S,比较资源1和资源3的优先级,假如任务1优先级高,才提升任务3,提升到能访问资源S的最高优先级,当任务3释放资源后,将优先级再调整回来。
-
优先级反转(Priority Inversion)
由于多进程共享资源,具有最高优先权的进程被低优先级进程阻塞,反而使具有中优先级的进程先于高优先级的进程执行,导致系统的崩溃。这就是所谓的优先级反转(Priority Inversion)。 -
产生原因
其实,优先级反转是在高优级(假设为A)的任务要访问一个被低优先级任务(假设为C)占有的资源时,被阻塞.而此时又有优先级高于占有资源的任务©而低于被阻塞的任务(A)的优先级的任务(假设为B)时,于是,占有资源的任务就被挂起(占有的资源仍为它占有),因为占有资源的任务优先级很低,所以,它可能一直被另外的任务挂起.而它占有的资源也就一直不能释放,这样,引起任务A一直没办法执行.而比它优先低的任务却可以执行.所以,一个解决办法就是提高占有资源任务的优先级,让它正常执行,然后释放资源,以让任务A能正常获取资源而得以执行.
-
解决方案 ( 优先级继承 / 优先级天花板 )
目前解决优先级反转有许多种方法。其中普遍使用的有2种方法:一种被称作优先级继承(priority inheritance);另一种被称作优先级极限(priority ceilings)。
A. 优先级继承(priority inheritance)
优先级继承是指将低优先级任务的优先级提升到等待它所占有的资源的最高优先级任务的优先级.当高优先级任务由于等待资源而被阻塞时,此时资源的拥有者的优先级将会自动被提升.
B. 优先级天花板(priority ceilings)
优先级天花板是指将申请某资源的任务的优先级提升到可能访问该资源的所有任务中最高优先级任务的优先级.(这个优先级称为该资源的优先级天花板)
A 和B的区别:
优先级继承,只有当占有资源的低优先级的任务被阻塞时,才会提高占有资源任务的优先级,而优先级天花板,不论是否发生阻塞,都提升.
优先级反转+解决方案