Linux内核中的同步与互斥(1)
Linux内核中的同步与互斥(1)
先看进程间的互斥。在linux内核中主要通过semaphore机制和spin_lock机制实现。主要的区别是在semaphore机制中,进不了临界区时会进行进程的切换,而spin_lock刚执行忙等在SMP中)。
先看内核中的semaphore机制。前提是对引用计数count增减的原子性操作。内核用ato
mic_t的数据结构和在它上面的一系列操作如atomic_add()、atomic_sub()等等实现。定义在atomic.h中)
semaphone机制主要通过up()和down()两个操作实现。
semaphone的结构为
- struct semaphore {
- atomic_t count;
- int sleepers;
- wait_queue_head_t wait;
- };
相应的down()函数为
- static inline void down(struct semaphore*sem)
- {
/* 1 */sem->count--; //为原子操作
- if(sem->count<0)
- {
- struct task_struct *tsk = current;
- DECLARE_WAITQUEUE(wait, tsk);
- tsk->state = TASK_UNINTERRUPTIBLE;
- add_wait_queue_exclusive(&sem->wait, &wait);
- spin_lock_irq(&semaphore_lock);
/* 2 */ sem->sleepers++;
- for (;;) {
- int sleepers = sem->sleepers;
- /*
- * Add "everybody else" into it. They aren't
- * playing, because we own the spinlock.
- */
/* 3 */ if (!atomic_add_negative(sleepers - 1, &sem->count)) {
/* 4 */ sem->sleepers = 0; //这时sem->count=0
- break;
- }
/* 4 */ sem->sleepers = 1; /* us - see -1 above */ // 这时sem
- ->count
- =-1
- spin_unlock_irq(&semaphore_lock);
- schedule();
- tsk->state = TASK_UNINTERRUPTIBLE;
- spin_lock_irq(&semaphore_lock);
- }
- spin_unlock_irq(&semaphore_lock);
- remove_wait_queue(&sem->wait, &wait);
- tsk->state = TASK_RUNNING;
- wake_up(&sem->wait);
- }
- }
相应的up()函数为
- void up(struct semaphore*sem)
- {
sem->count++; //为原子操作
- if(sem->count<=0)
- {
//唤醒等待队列中的一个符合条件的进程因为每个进程都加了TASK_EXCLUSIVE标志)
。
};
假设开始时,count=1;sleepers=0
评论暂时关闭