本文共 3038 字,大约阅读时间需要 10 分钟。
单核处理器+抢占 与 多核处理器在许多发面有类似的特性。
一般对于本地CPU(就是此刻运行这个代码的CPU或者CPU核),控制其中断使用的函数是:
调度器的控制函数:
以上是并发的来源,而下面的方法都是对并发的处理和控制,因此都是全局的。
自旋锁不会引起调用者睡眠,如果自旋锁已经被别的执行单元保持,调用者就一直循环 查看是否该自旋锁的保持者已经释放了锁,“自旋”就是“在原地打转”。而信号量则引起调 用者睡眠,它把进程从运行队列上拖出去,除非获得锁。
spin_lock,禁止抢占,并且用一个变量来指明资源是否真正被使用。
spin_lock因为没有禁止中断,所以有可能出现死锁
在A进程用自旋锁锁住并使用资源B,处于临界区中,接着被中断,而中断中又去尝试使用资源B,这将造成死锁
spin 结构体中里面有个变量,这个变量在spin_lock中被原子改变。因此其他地方再去spin_lock的时候会发现这个变量已经改变,表明锁已经被使用了,此时将在这里自旋等待。
spin_lock_irq(Save)=spin_lock + disableIRQ
而普通的spin_lock为
spin_lock=原子设置V + preempt_disable
这个使得就解决了上面因为中断而造成的死锁的可能性。 2. spin_lock_bh
disable softIRQ
允许调用它的进程进入睡眠放入到wait_list中,见下面的结构体成员。
/* Please don't access any members of this structure directly */struct semaphore {
spinlock_t lock; unsigned int count; struct list_head wait_list; }; 1. lock:一个自旋锁用于对count变量的原子更改。 1. count:记录资源数目。 1. wait_list:将无法获取信号量的进程放入队列中。
count++;唤醒在wait_list中的等待进程
struct mutex {/* 1: unlocked, 0: locked, negative: locked, possible waiters */
atomic_t count;
spinlock_t wait_lock; struct list_head wait_list;
#if defined(CONFIG_DEBUG_MUTEXES) || defined(CONFIG_SMP)
struct task_struct
#endif
owner;
#ifdef CONFIG_DEBUG_MUTEXES
#endif #ifdef CONFIG_DEBUG_MUTEXES
const char name;
void *magic;
#endif #ifdef CONFIG_DEBUG_LOCK_ALLOC
struct lockdep_map dep_map;
#endif };
struct mutex { / 1: unlocked, 0: locked, negative: locked, possible waiters / atomic_t count; spinlock_t wait_lock; struct list_head wait_list; }; 与上面的semophore相比,就是count的类型从unsigned int编程了atomic_t,且用1表示没有被锁,0表示锁了。而semophore里面的count则是用来表示可以获取资源的数目。互斥锁就是用来表示一个进程可以获取资源的。
与semophore一致有UP和DOWN。
RCU = preempt_disable + 每次写都分配一个新空间
必须在临界区读。
①来源于深入Linux设备驱动程序内核机制
②
如果文章有格式问题,请移步:
转载请注明出处。作者:TonyHo hexiongjun.com