C++类与对象在定义对象时为什么会这样
教教我把,是代码哪里出了问题吗
代码错误不在这里,在42行
cpu
,并且开了抢占可以造成这种情况。(???)schedule
或进程阻塞(此也会导致调用schedule)
时,还是会发生进程调度的。而单核情况下自旋锁其实是空的,啥都没干 !参考:
linux
上的自旋锁有三种实现:
cpu
,不可抢占内核中,自旋锁为空操作(就是什么也不做)。cpu
,可抢占内核中,自旋锁实现为“禁止内核抢占”,并不实现“自旋”。cpu
,可抢占内核中,自旋锁实现为“禁止内核抢占” + “自旋”。关于抢占式内核
与非抢占式内核
:
cpu
(即主动调用schedule或内核中的任务阻塞——这同样也会导致调用schedule)cpu
(即主动调用schedule或内核中的任务阻塞——这同样也会导致调用schedule)禁止内核抢占只是关闭“可抢占标志”,而不是禁止进程切换。显式使用schedule
或进程阻塞(此也会导致调用schedule)
时,还是会发生进程调度的。, 这就是同时又两个进程获得了资源所的原因 !!!
死锁
第一种死锁情况: 死锁发生在多核的情况
A
,B
两个CPU
。A
上正在运行的a进程
已获得自旋锁,并在临界区运行。B
上正在运行的b进程
企图获得自旋锁,但由于自旋锁已被占用,于是b进程
在B CPU
上“自旋”空转。A
上的a进程
因程序阻塞,而被休眠。接着A
会切换运行另一进程c
。进程c
也企图获取自旋锁,c进程同样会因为锁已被占用,而在A
上“自旋”空转。A
上的a进程
与c进程
就形成了死锁。a进程
需要被c进程
占用的CPU
,c进程
需要被a进程
占用的锁。单cpu内核
上不会出现上述情况,因为单cpu
上的自旋锁实际没有“自旋功能”。第二种死锁情况
第三种死锁情况
spin_lock
比spin_lock_irq
速度快,但是它并不是任何情况下都是安全的。进程A
中调用了spin_lock(&lock)
然后进入临界区,此时来了一个中断(interrupt)
,该中断也运行在和进程A
相同的CPU
上,并且在该中断处理程序中恰巧也会spin_lock(&lock)
试图获取同一个锁。由于是在同一个CPU
上被中断,进程A
会被设置为TASK_INTERRUPT
状态,中断处理程序无法获得锁,会不停的忙等,由于进程A
被设置为中断状态,schedule()
进程调度就无法再调度进程A
运行,这样就导致了死锁!CPU
上就不会触发死锁。 因为在不同的CPU
上出现中断不会导致进程A
的状态被设为TASK_INTERRUPT
,只是换出。当中断处理程序忙等被换出后,进程A
还是有机会获得CPU
,执行并退出临界区。所以在使用spin_lock
时要明确知道该锁不会在中断处理程序中使用。自旋锁有几个重要的特性:
linux
在设计可抢占式系统的自旋锁时只是把自旋锁设计为"只是禁止内核抢占",而没有自旋(所以使用自旋锁的代码一定要可以很快执行完,否则进程就一直持着锁不释放,也不可被抢占).