用户态自旋锁和内核态自旋锁的区别?
如题,小弟内核菜鸟,最近研究自旋锁,发现用户态也有自旋锁实现(如pthread),不知道用户态下的自旋锁和内核态的区别是什么?或者说用户态下的自旋锁实现原理是什么?还望大神赐教。 不负责任的回答,用户的锁最后也用的内核里面的。 回复 1# DVD0423
我有点不同意amarant的解析,有点以偏概全。
其实这个问题的核心就是什么才叫spinlock?只要符合拿不到锁时自旋等待而是不去睡眠这个条件,就符合自旋锁的定义,它的实现就是一个自旋锁的!不管在那实现,不管最终的实现会有什么其它的效果。
跟拿到锁以后是否还会被调度走没有关系,其实内核的spinlock实现在打开内核抢占时,拿不到锁,也会被调度出去。
http://www.unix.com/man-page/freebsd/3/pthread_spin_lock/
The pthread_spin_lock() function will acquire lock if it is not currently owned by another
thread.If the lock cannot be acquired immediately, it will spin attempting to acquire the
lock (it will not sleep) until it becomes available.
回复 3# Tinnal
有个疑问请教下:
内核的spinlock实现在打开内核抢占时,拿不到锁,也会被调度出去。
疑问:内核开抢占时,拿不到锁就被调度,就违背自旋的本意了吧?
本帖最后由 Tinnal 于 2015-01-31 08:42 编辑
回复 4# 镇水铁牛
没有违背呀。1. 从代码来说,它还在自我的循环里;2.它的状态还是running的状态,没有去睡眠等待。 回复 3# Tinnal
下面是linux-2.6.10的代码:#define spin_lock(lock) _spin_lock(lock)
void __lockfunc _spin_lock(spinlock_t *lock)
{
preempt_disable();
if (unlikely(!_raw_spin_trylock(lock)))
__preempt_spin_lock(lock);
}
static inline void __preempt_spin_lock(spinlock_t *lock)
{
if (preempt_count() > 1) {
_raw_spin_lock(lock);
return;
}
do {
preempt_enable();
while (spin_is_locked(lock))
cpu_relax();
preempt_disable();
} while (!_raw_spin_trylock(lock));
}=============================================================
下面是linux-3.10.0的代码:static inline void spin_lock(spinlock_t *lock)
{
raw_spin_lock(&lock->rlock);
}
#define raw_spin_lock(lock) _raw_spin_lock(lock)
void __lockfunc _raw_spin_lock(raw_spinlock_t *lock)
{
__raw_spin_lock(lock);
}
static inline void __raw_spin_lock(raw_spinlock_t *lock)
{
preempt_disable();
spin_acquire(&lock->dep_map, 0, 0, _RET_IP_);
LOCK_CONTENDED(lock, do_raw_spin_trylock, do_raw_spin_lock);
}
static inline void do_raw_spin_lock(raw_spinlock_t *lock) __acquires(lock)
{
__acquire(lock);
arch_spin_lock(&lock->raw_lock);
}
static __always_inline void arch_spin_lock(arch_spinlock_t *lock)
{
register struct __raw_tickets inc = { .tail = TICKET_LOCK_INC };
inc = xadd(&lock->tickets, inc);
if (likely(inc.head == inc.tail))
goto out;
inc.tail &= ~TICKET_SLOWPATH_FLAG;
for (;;) {
unsigned count = SPIN_THRESHOLD;
do {
if (ACCESS_ONCE(lock->tickets.head) == inc.tail)
goto out;
cpu_relax();
} while (--count);
__ticket_lock_spinning(lock, inc.tail);
}
out: barrier(); /* make sure nothing creeps before the lock is taken */
}新版本取消了自旋等待过程中的抢占使能。
我知道你的意思,可能我没表述清楚,我想说的是他们的底层是不是一样的,比如X86架构,他们的实现是不是用的相同的指令。因为我最近做的实验是检测自旋锁时间,这样就出现一个问题,到底是只检测内核中的还是也要检测用户层下的?回复 3# Tinnal
回复 7# DVD0423
代码肯定是不一样的呀,而且用户态和内核态没有可比性。 回复 8# Tinnal 我的关键问题就是想知道这两个不一样的地方。比如一个带有自旋锁的程序到底在指令层是不是调用了内核的自旋锁?这涉及到我的自旋锁检测的实验是不是只需要检测内核层,请问您了解吗?求指导。
pthread_spin_lock应该是没有调用内核的Spinlock实现的。内核的spinlock不是一个系统调用。